/*****************************************************************************
 * Copyright (c) 2014-2024 OpenRCT2 developers
 *
 * For a complete list of all authors, please refer to contributors.md
 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
 *
 * OpenRCT2 is licensed under the GNU General Public License version 3.
 *****************************************************************************/

#include "../../../drawing/Drawing.h"
#include "../../../interface/Viewport.h"
#include "../../../object/StationObject.h"
#include "../../../ride/RideData.h"
#include "../../../ride/TrackData.h"
#include "../../../ride/TrackPaint.h"
#include "../../../sprites.h"
#include "../../../world/Map.h"
#include "../../Paint.h"
#include "../../support/MetalSupports.h"
#include "../../tile_element/Segment.h"
#include "../../track/Segment.h"
#include "../../track/Support.h"

#include <algorithm>

using namespace OpenRCT2;

enum class JuniorRCSubType : uint8_t
{
    Junior = 1,
    WaterCoaster = 2,
};

enum
{
    SPR_JUNIOR_RC_FLAT_SW_NE = 27807,
    SPR_JUNIOR_RC_FLAT_NW_SE = 27808,
    SPR_JUNIOR_RC_25_DEG_SW_NE = 27809,
    SPR_JUNIOR_RC_60_DEG_SW_NE = 27810,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_SW_NE = 27811,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_SW_NE = 27812,
    SPR_JUNIOR_RC_25_DEG_NE_SW = 27813,
    SPR_JUNIOR_RC_60_DEG_NE_SW = 27814,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_NE_SW = 27815,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NE_SW_PART_0_2 = 27816,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_NE_SW = 27817,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NE_SW_PART_0_2 = 27818,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_SW_NE = 27819,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_SW_NE = 27820,
    SPR_JUNIOR_RC_25_DEG_NW_SE = 27821,
    SPR_JUNIOR_RC_60_DEG_NW_SE = 27822,
    SPR_JUNIOR_RC_25_DEG_SE_NW = 27823,
    SPR_JUNIOR_RC_60_DEG_SE_NW = 27824,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_NW_SE = 27825,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NW_SE_PART_0_2 = 27826,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_SE_NW = 27827,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_SE_NW = 27828,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_SE_NW = 27829,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_SE_NW = 27830,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_NW_SE = 27831,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NW_SE_PART_0_2 = 27832,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_0 = 27833,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_1 = 27834,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_2 = 27835,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_3 = 27836,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_4 = 27837,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_0 = 27838,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_1 = 27839,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_2 = 27840,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_3 = 27841,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_4 = 27842,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_0 = 27843,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_1 = 27844,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_2 = 27845,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_3 = 27846,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_4 = 27847,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_0 = 27848,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_1 = 27849,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_2 = 27850,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_3 = 27851,
    SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_4 = 27852,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NE_SW = 27853,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NE_SW = 27854,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NW_SE = 27855,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NW_SE = 27856,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_0 = 27857,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_1 = 27858,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_2 = 27859,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_3 = 27860,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_4 = 27861,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_0 = 27862,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_1 = 27863,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_2 = 27864,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_3 = 27865,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_4 = 27866,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_0 = 27867,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_1 = 27868,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_2 = 27869,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_3 = 27870,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_4 = 27871,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_0 = 27872,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_1 = 27873,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_2 = 27874,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_3 = 27875,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_4 = 27876,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_0 = 27877,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_1 = 27878,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_2 = 27879,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_3 = 27880,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_4 = 27881,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_0 = 27882,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_1 = 27883,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_2 = 27884,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_3 = 27885,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_4 = 27886,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_0 = 27887,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_1 = 27888,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_2 = 27889,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_3 = 27890,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_4 = 27891,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_0 = 27892,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_1 = 27893,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_2 = 27894,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_3 = 27895,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_4 = 27896,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_0 = 27897,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_1 = 27898,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_2 = 27899,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_3 = 27900,
    SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_0 = 27901,
    SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_1 = 27902,
    SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_2 = 27903,
    SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_3 = 27904,
    SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_0 = 27905,
    SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_1 = 27906,
    SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_2 = 27907,
    SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_3 = 27908,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_0 = 27909,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_1 = 27910,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_2 = 27911,
    SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_3 = 27912,
    SPR_JUNIOR_RC_FLAT_CHAIN_SW_NE = 27913,
    SPR_JUNIOR_RC_FLAT_CHAIN_NW_SE = 27914,
    SPR_JUNIOR_RC_25_DEG_CHAIN_SW_NE = 27915,
    SPR_JUNIOR_RC_60_DEG_CHAIN_SW_NE = 27916,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_SW_NE = 27917,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_SW_NE = 27918,
    SPR_JUNIOR_RC_25_DEG_CHAIN_NE_SW = 27919,
    SPR_JUNIOR_RC_60_DEG_CHAIN_NE_SW = 27920,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_NE_SW = 27921,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NE_SW_PART_0_2 = 27922,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_NE_SW = 27923,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NE_SW_PART_0_2 = 27924,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_SW_NE = 27925,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_SW_NE = 27926,
    SPR_JUNIOR_RC_25_DEG_CHAIN_NW_SE = 27927,
    SPR_JUNIOR_RC_60_DEG_CHAIN_NW_SE = 27928,
    SPR_JUNIOR_RC_25_DEG_CHAIN_SE_NW = 27929,
    SPR_JUNIOR_RC_60_DEG_CHAIN_SE_NW = 27930,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_NW_SE = 27931,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NW_SE_PART_0_2 = 27932,
    SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_SE_NW = 27933,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_SE_NW = 27934,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_SE_NW = 27935,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_SE_NW = 27936,
    SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_NW_SE = 27937,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NW_SE_PART_0_2 = 27938,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NE_SW = 27939,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NE_SW = 27940,
    SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NW_SE = 27941,
    SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NW_SE = 27942,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_0 = 27943,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_1 = 27944,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_2 = 27945,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_3 = 27946,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_4 = 27947,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_0 = 27948,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_1 = 27949,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_2 = 27950,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_3 = 27951,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_4 = 27952,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_0 = 27953,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_1 = 27954,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_2 = 27955,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_3 = 27956,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_4 = 27957,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_0 = 27958,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_1 = 27959,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_2 = 27960,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_3 = 27961,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_4 = 27962,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_0 = 27963,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_1 = 27964,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_2 = 27965,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_3 = 27966,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_4 = 27967,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_0 = 27968,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_1 = 27969,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_2 = 27970,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_3 = 27971,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_4 = 27972,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_0 = 27973,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_1 = 27974,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_2 = 27975,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_3 = 27976,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_4 = 27977,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_0 = 27978,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_1 = 27979,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_2 = 27980,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_3 = 27981,
    SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_4 = 27982,
    SPR_WATER_RC_FLAT_CHAIN_SW_NE = 27983,
    SPR_WATER_RC_FLAT_CHAIN_NW_SE = 27984,
    SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_SW_NE = 27985,
    SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_NW_SE = 27986,
    SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_NE_SW = 27987,
    SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_SE_NW = 27988,
    SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_SW_NE = 27989,
    SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_NW_SE = 27990,
    SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_NE_SW = 27991,
    SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_SE_NW = 27992,
    SPR_WATER_RC_25_DEG_CHAIN_SW_NE = 27993,
    SPR_WATER_RC_25_DEG_CHAIN_NW_SE = 27994,
    SPR_WATER_RC_25_DEG_CHAIN_NE_SW = 27995,
    SPR_WATER_RC_25_DEG_CHAIN_SE_NW = 27996,
    SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_SW_NE = 27997,
    SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_NW_SE = 27998,
    SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_NE_SW = 27999,
    SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_SE_NW = 28000,
    SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_SW_NE = 28001,
    SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_NW_SE = 28002,
    SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_NE_SW = 28003,
    SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_SE_NW = 28004,
    SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_SW_NE_FRONT = 28005,
    SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_NW_SE_FRONT = 28006,
    SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_NE_SW_FRONT = 28007,
    SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_SE_NW_FRONT = 28008,
    SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_SW_NE = 28009,
    SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_NW_SE = 28010,
    SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_NE_SW = 28011,
    SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_SE_NW = 28012,
    SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_SW_NE_FRONT = 28013,
    SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_NW_SE_FRONT = 28014,
    SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_SW_NE = 28015,
    SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_NW_SE = 28016,
    SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_NE_SW = 28017,
    SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_SE_NW = 28018,
    SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_NE_SW_FRONT = 28019,
    SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_SE_NW_FRONT = 28020,
    SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_SW_NE = 28021,
    SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_NW_SE = 28022,
    SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_NE_SW = 28023,
    SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_SE_NW = 28024,
    SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_SW_NE_FRONT = 28025,
    SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_NW_SE_FRONT = 28026,
    SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_SW_NE = 28027,
    SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_NW_SE = 28028,
    SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_NE_SW = 28029,
    SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_SE_NW = 28030,
    SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_NE_SW_FRONT = 28031,
    SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_SE_NW_FRONT = 28032,
    SPR_JUNIOR_RC_LEFT_BANK_SW_NE = 28033,
    SPR_JUNIOR_RC_LEFT_BANK_NW_SE = 28034,
    SPR_JUNIOR_RC_LEFT_BANK_NE_SW = 28035,
    SPR_JUNIOR_RC_LEFT_BANK_SE_NW = 28036,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_0 = 28037,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_1 = 28038,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_2 = 28039,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_3 = 28040,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_4 = 28041,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_0 = 28042,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_1 = 28043,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_2 = 28044,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_3 = 28045,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_4 = 28046,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_0 = 28047,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_1 = 28048,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_2 = 28049,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_3 = 28050,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_4 = 28051,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_0 = 28052,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_1 = 28053,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_2 = 28054,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_3 = 28055,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_4 = 28056,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_4_2 = 28057,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_0_2 = 28058,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SW_SE_PART_0 = 28059,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SW_SE_PART_1 = 28060,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SW_SE_PART_2 = 28061,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NW_SW_PART_0 = 28062,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NW_SW_PART_1 = 28063,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NW_SW_PART_2 = 28064,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NE_NW_PART_0 = 28065,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NE_NW_PART_1 = 28066,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NE_NW_PART_2 = 28067,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SE_NE_PART_0 = 28068,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SE_NE_PART_1 = 28069,
    SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SE_NE_PART_2 = 28070,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SW_SE_PART_0 = 28071,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SW_SE_PART_1 = 28072,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SW_SE_PART_2 = 28073,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_0 = 28074,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_1 = 28075,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_2 = 28076,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NE_NW_PART_0 = 28077,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NE_NW_PART_1 = 28078,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NE_NW_PART_2 = 28079,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_0 = 28080,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_1 = 28081,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_2 = 28082,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_2_2 = 28083,
    SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_0_2 = 28084,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SW_SE_PART_0 = 28085,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SW_SE_PART_1 = 28086,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NW_SW_PART_0 = 28087,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NW_SW_PART_1 = 28088,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NE_NW_PART_0 = 28089,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NE_NW_PART_1 = 28090,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SE_NE_PART_0 = 28091,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SE_NE_PART_1 = 28092,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SW_SE_PART_0 = 28093,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SW_SE_PART_1 = 28094,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NW_SW_PART_0 = 28095,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NW_SW_PART_1 = 28096,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NE_NW_PART_0 = 28097,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NE_NW_PART_1 = 28098,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SE_NE_PART_0 = 28099,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SE_NE_PART_1 = 28100,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SW_SE_PART_0 = 28101,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SW_SE_PART_1 = 28102,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NW_SW_PART_0 = 28103,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NW_SW_PART_1 = 28104,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NE_NW_PART_0 = 28105,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NE_NW_PART_1 = 28106,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SE_NE_PART_0 = 28107,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SE_NE_PART_1 = 28108,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SW_SE_PART_0 = 28109,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SW_SE_PART_1 = 28110,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NW_SW_PART_0 = 28111,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NW_SW_PART_1 = 28112,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NE_NW_PART_0 = 28113,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NE_NW_PART_1 = 28114,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SE_NE_PART_0 = 28115,
    SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SE_NE_PART_1 = 28116,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SW_SE_PART_0 = 28117,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SW_SE_PART_1 = 28118,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SW_SE_PART_2 = 28119,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_0 = 28120,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_1 = 28121,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_2 = 28122,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NE_NW_PART_0 = 28123,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NE_NW_PART_1 = 28124,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NE_NW_PART_2 = 28125,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_0 = 28126,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_1 = 28127,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_2 = 28128,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_2_2 = 28129,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_0_2 = 28130,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SW_SE_PART_0 = 28131,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SW_SE_PART_1 = 28132,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SW_SE_PART_2 = 28133,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_0 = 28134,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_1 = 28135,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_2 = 28136,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NE_NW_PART_0 = 28137,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NE_NW_PART_1 = 28138,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NE_NW_PART_2 = 28139,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_0 = 28140,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_1 = 28141,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_2 = 28142,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_2_2 = 28143,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_0_2 = 28144,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_0 = 28145,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_1 = 28146,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_2 = 28147,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_3 = 28148,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_4 = 28149,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_0 = 28150,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_1 = 28151,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_2 = 28152,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_3 = 28153,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_4 = 28154,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_0 = 28155,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_1 = 28156,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_2 = 28157,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_3 = 28158,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_4 = 28159,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_0 = 28160,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_1 = 28161,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_2 = 28162,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_3 = 28163,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_4 = 28164,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_4_2 = 28165,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_0_2 = 28166,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_0 = 28167,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_1 = 28168,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_2 = 28169,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_3 = 28170,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_4 = 28171,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_0 = 28172,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_1 = 28173,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_2 = 28174,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_3 = 28175,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_4 = 28176,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_0 = 28177,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_1 = 28178,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_2 = 28179,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_3 = 28180,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_4 = 28181,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_0 = 28182,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_1 = 28183,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_2 = 28184,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_3 = 28185,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_4 = 28186,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_4_2 = 28187,
    SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_0_2 = 28188,
    SPR_JUNIOR_RC_STATION_SW_NE = 28189,
    SPR_JUNIOR_RC_STATION_NW_SE = 28190,
    SPR_JUNIOR_RC_FLAT_SW_NE_BRAKED = 28191,
    SPR_JUNIOR_RC_FLAT_NW_SE_BRAKED = 28192,
    SPR_JUNIOR_RC_FLAT_BLOCK_SW_NE = 28193,
    SPR_JUNIOR_RC_FLAT_BLOCK_NW_SE = 28194,
    SPR_JUNIOR_RC_FLAT_BLOCK_SW_NE_BRAKED = 28195,
    SPR_JUNIOR_RC_FLAT_BLOCK_NW_SE_BRAKED = 28196,
    SPR_JUNIOR_RC_DIAG_FLAT_W_E = 28197,
    SPR_JUNIOR_RC_DIAG_FLAT_N_S = 28198,
    SPR_JUNIOR_RC_DIAG_FLAT_E_W = 28199,
    SPR_JUNIOR_RC_DIAG_FLAT_S_N = 28200,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_W_E = 28201,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_N_S = 28202,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_E_W = 28203,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_S_N = 28204,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_W_E = 28205,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_N_S = 28206,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_E_W = 28207,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_S_N = 28208,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_W_E = 28209,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_N_S = 28210,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_E_W = 28211,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_S_N = 28212,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_W_E = 28213,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_N_S = 28214,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_E_W = 28215,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_S_N = 28216,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_W_E = 28217,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_N_S = 28218,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_E_W = 28219,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_S_N = 28220,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_W_E = 28221,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_N_S = 28222,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_E_W = 28223,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_S_N = 28224,

    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_W_E = 28225,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_N_S = 28226,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_E_W = 28227,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_S_N = 28228,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_W_E = 28229,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_N_S = 28230,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_E_W = 28231,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_S_N = 28232,

    SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_W_E = 28233,
    SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_N_S = 28234,
    SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_E_W = 28235,
    SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_S_N = 28236,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_W_E = 28237,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_N_S = 28238,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_E_W = 28239,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_S_N = 28240,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_W_E = 28241,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_N_S = 28242,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_E_W = 28243,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_S_N = 28244,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_W_E = 28245,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_N_S = 28246,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_E_W = 28247,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_S_N = 28248,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_W_E = 28249,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_N_S = 28250,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_E_W = 28251,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_S_N = 28252,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_W_E = 28253,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_N_S = 28254,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_E_W = 28255,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_S_N = 28256,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_W_E = 28257,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_N_S = 28258,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_E_W = 28259,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_S_N = 28260,

    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_W_E = 28261,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_N_S = 28262,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_E_W = 28263,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_S_N = 28264,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_W_E = 28265,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_N_S = 28266,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_E_W = 28267,
    SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_S_N = 28268,

    SPR_WATER_RC_DIAG_FLAT_CHAIN_W_E = 28269,
    SPR_WATER_RC_DIAG_FLAT_CHAIN_N_S = 28270,
    SPR_WATER_RC_DIAG_FLAT_CHAIN_E_W = 28271,
    SPR_WATER_RC_DIAG_FLAT_CHAIN_S_N = 28272,
    SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_W_E = 28273,
    SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_N_S = 28274,
    SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_E_W = 28275,
    SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_S_N = 28276,
    SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_W_E = 28277,
    SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_N_S = 28278,
    SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_E_W = 28279,
    SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_S_N = 28280,
    SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_W_E = 28281,
    SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_N_S = 28282,
    SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_E_W = 28283,
    SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_S_N = 28284,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_0 = 28285,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_1 = 28286,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_2 = 28287,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_3 = 28288,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_0 = 28289,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_1 = 28290,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_2 = 28291,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_3 = 28292,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_0 = 28293,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_1 = 28294,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_2 = 28295,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_3 = 28296,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_0 = 28297,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_1 = 28298,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_2 = 28299,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_3 = 28300,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_0 = 28301,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_1 = 28302,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_2 = 28303,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_3 = 28304,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_0 = 28305,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_1 = 28306,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_2 = 28307,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_3 = 28308,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_0 = 28309,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_1 = 28310,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_2 = 28311,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_3 = 28312,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_0 = 28313,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_1 = 28314,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_2 = 28315,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_3 = 28316,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_0 = 28317,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_1 = 28318,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_2 = 28319,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_3 = 28320,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_0 = 28321,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_1 = 28322,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_2 = 28323,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_3 = 28324,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_0 = 28325,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_1 = 28326,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_2 = 28327,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_3 = 28328,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_0 = 28329,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_1 = 28330,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_2 = 28331,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_3 = 28332,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_0 = 28333,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_1 = 28334,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_2 = 28335,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_3 = 28336,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_0 = 28337,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_1 = 28338,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_2 = 28339,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_3 = 28340,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_0 = 28341,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_1 = 28342,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_2 = 28343,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_3 = 28344,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_0 = 28345,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_1 = 28346,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_2 = 28347,
    SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_3 = 28348,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_W_E = 28349,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_N_S = 28350,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_E_W = 28351,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_S_N = 28352,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_W_E = 28353,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_N_S = 28354,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_E_W = 28355,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_S_N = 28356,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_W_E_PART_0_2 = 28357,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_W_E = 28358,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_N_S = 28359,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_E_W = 28360,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_S_N = 28361,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_E_W_PART_0_2 = 28362,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_W_E = 28363,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_N_S = 28364,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_E_W = 28365,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_S_N = 28366,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_W_E_PART_0_2 = 28367,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_W_E = 28368,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_N_S = 28369,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_E_W = 28370,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_S_N = 28371,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_E_W_PART_0_2 = 28372,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_W_E = 28373,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_N_S = 28374,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_E_W = 28375,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_S_N = 28376,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_W_E_PART_0_2 = 28377,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_W_E = 28378,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_N_S = 28379,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_E_W = 28380,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_S_N = 28381,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_E_W_PART_0_2 = 28382,
    SPR_JUNIOR_RC_DIAG_BRAKES_E_W = SPR_G2_JUNIOR_DIAG_BRAKES,
    SPR_JUNIOR_RC_DIAG_BRAKES_N_S = SPR_G2_JUNIOR_DIAG_BRAKES + 1,
    SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_E_W_CLOSED = SPR_G2_JUNIOR_DIAG_BRAKES + 2,
    SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_E_W_OPEN = SPR_G2_JUNIOR_DIAG_BRAKES + 3,
    SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_N_S_CLOSED = SPR_G2_JUNIOR_DIAG_BRAKES + 4,
    SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_N_S_OPEN = SPR_G2_JUNIOR_DIAG_BRAKES + 5,
};

static constexpr uint32_t junior_rc_track_pieces_flat[3][4] = {
    {
        SPR_JUNIOR_RC_FLAT_SW_NE,
        SPR_JUNIOR_RC_FLAT_NW_SE,
        SPR_JUNIOR_RC_FLAT_SW_NE,
        SPR_JUNIOR_RC_FLAT_NW_SE,
    },
    {
        SPR_JUNIOR_RC_FLAT_CHAIN_SW_NE,
        SPR_JUNIOR_RC_FLAT_CHAIN_NW_SE,
        SPR_JUNIOR_RC_FLAT_CHAIN_SW_NE,
        SPR_JUNIOR_RC_FLAT_CHAIN_NW_SE,
    },
    {
        SPR_WATER_RC_FLAT_CHAIN_SW_NE,
        SPR_WATER_RC_FLAT_CHAIN_NW_SE,
        SPR_WATER_RC_FLAT_CHAIN_SW_NE,
        SPR_WATER_RC_FLAT_CHAIN_NW_SE,
    },
};

static constexpr uint32_t junior_rc_track_pieces_block_brake[2][4] = {
    {
        SPR_JUNIOR_RC_FLAT_BLOCK_SW_NE,
        SPR_JUNIOR_RC_FLAT_BLOCK_NW_SE,
        SPR_JUNIOR_RC_FLAT_BLOCK_SW_NE,
        SPR_JUNIOR_RC_FLAT_BLOCK_NW_SE,
    },
    {
        SPR_JUNIOR_RC_FLAT_BLOCK_SW_NE_BRAKED,
        SPR_JUNIOR_RC_FLAT_BLOCK_NW_SE_BRAKED,
        SPR_JUNIOR_RC_FLAT_BLOCK_SW_NE_BRAKED,
        SPR_JUNIOR_RC_FLAT_BLOCK_NW_SE_BRAKED,
    },
};

static constexpr uint32_t junior_rc_track_pieces_station[2][4] = {
    {
        SPR_JUNIOR_RC_STATION_SW_NE,
        SPR_JUNIOR_RC_STATION_NW_SE,
        SPR_JUNIOR_RC_STATION_SW_NE,
        SPR_JUNIOR_RC_STATION_NW_SE,
    },
    {
        SPR_JUNIOR_RC_FLAT_SW_NE_BRAKED,
        SPR_JUNIOR_RC_FLAT_NW_SE_BRAKED,
        SPR_JUNIOR_RC_FLAT_SW_NE_BRAKED,
        SPR_JUNIOR_RC_FLAT_NW_SE_BRAKED,
    },
};

static constexpr uint32_t junior_rc_track_pieces_25_deg_up[3][4] = {
    {
        SPR_JUNIOR_RC_25_DEG_SW_NE,
        SPR_JUNIOR_RC_25_DEG_NW_SE,
        SPR_JUNIOR_RC_25_DEG_NE_SW,
        SPR_JUNIOR_RC_25_DEG_SE_NW,
    },
    {
        SPR_JUNIOR_RC_25_DEG_CHAIN_SW_NE,
        SPR_JUNIOR_RC_25_DEG_CHAIN_NW_SE,
        SPR_JUNIOR_RC_25_DEG_CHAIN_NE_SW,
        SPR_JUNIOR_RC_25_DEG_CHAIN_SE_NW,
    },
    {
        SPR_WATER_RC_25_DEG_CHAIN_SW_NE,
        SPR_WATER_RC_25_DEG_CHAIN_NW_SE,
        SPR_WATER_RC_25_DEG_CHAIN_NE_SW,
        SPR_WATER_RC_25_DEG_CHAIN_SE_NW,
    },
};

static constexpr uint32_t junior_rc_track_pieces_flat_to_25_deg_up[3][4] = {
    {
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_SW_NE,
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_NW_SE,
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_NE_SW,
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_SE_NW,
    },
    {
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_SW_NE,
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_NW_SE,
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_NE_SW,
        SPR_JUNIOR_RC_FLAT_TO_25_DEG_UP_CHAIN_SE_NW,
    },
    {
        SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_SW_NE,
        SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_NW_SE,
        SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_NE_SW,
        SPR_WATER_RC_FLAT_TO_25_DEG_UP_CHAIN_SE_NW,
    },
};

static constexpr uint32_t junior_rc_track_pieces_25_deg_up_to_flat[3][4] = {
    {
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_SW_NE,
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_NW_SE,
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_NE_SW,
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_SE_NW,
    },
    {
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_SW_NE,
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_NW_SE,
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_NE_SW,
        SPR_JUNIOR_RC_25_DEG_UP_TO_FLAT_CHAIN_SE_NW,
    },
    {
        SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_SW_NE,
        SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_NW_SE,
        SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_NE_SW,
        SPR_WATER_RC_25_DEG_UP_TO_FLAT_CHAIN_SE_NW,
    },
};

static constexpr uint32_t junior_rc_track_pieces_flat_to_left_bank[4][2] = {
    { SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_SW_NE, SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_SW_NE_FRONT },
    { SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_NW_SE, SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_NW_SE_FRONT },
    { SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_NE_SW, 0 },
    { SPR_JUNIOR_RC_FLAT_TO_LEFT_BANK_SE_NW, 0 }
};

static constexpr uint32_t junior_rc_track_pieces_flat_to_right_bank[4][2] = {
    { SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_SW_NE, 0 },
    { SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_NW_SE, 0 },
    { SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_NE_SW, SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_NE_SW_FRONT },
    { SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_SE_NW, SPR_JUNIOR_RC_FLAT_TO_RIGHT_BANK_SE_NW_FRONT },
};

static constexpr uint32_t junior_rc_track_pieces_flat_quarter_turn_5_tiles[4][5] = {
    {
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_0,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_1,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_2,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_3,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SW_SE_PART_4,
    },
    {
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_0,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_1,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_2,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_3,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NW_SW_PART_4,
    },
    {
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_0,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_1,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_2,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_3,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_NE_NW_PART_4,
    },
    {
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_0,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_1,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_2,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_3,
        SPR_JUNIOR_RC_FLAT_QUARTER_TURN_5_TILES_SE_NE_PART_4,
    },
};

static constexpr uint32_t junior_rc_track_pieces_banked_quarter_turn_5_tiles[4][5] = {
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_2,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_3,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SW_SE_PART_4,
    },
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_2,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_3,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_4,
    },
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_2,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_3,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NE_NW_PART_4,
    },
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_2,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_3,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_4,
    },
};

static constexpr uint32_t junior_rc_track_pieces_left_banked_to_25_deg_up[4][2] = {
    { SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_SW_NE, SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_SW_NE_FRONT },
    { SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_NW_SE, SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_NW_SE_FRONT },
    { SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_NE_SW, 0 },
    { SPR_JUNIOR_RC_LEFT_BANK_TO_25_DEG_UP_SE_NW, 0 },
};

static constexpr uint32_t junior_rc_track_pieces_right_banked_to_25_deg_up[4][2] = {
    { SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_SW_NE, 0 },
    { SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_NW_SE, 0 },
    { SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_NE_SW, SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_NE_SW_FRONT },
    { SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_SE_NW, SPR_JUNIOR_RC_RIGHT_BANK_TO_25_DEG_UP_SE_NW_FRONT },
};

static constexpr uint32_t junior_rc_track_pieces_25_deg_up_to_left_bank[4][2] = {
    { SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_SW_NE, SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_SW_NE_FRONT },
    { SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_NW_SE, SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_NW_SE_FRONT },
    { SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_NE_SW, 0 },
    { SPR_JUNIOR_RC_25_DEG_UP_TO_LEFT_BANK_SE_NW, 0 },
};

static constexpr uint32_t junior_rc_track_pieces_25_deg_up_to_right_bank[4][2] = {
    { SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_SW_NE, 0 },
    { SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_NW_SE, 0 },
    { SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_NE_SW, SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_NE_SW_FRONT },
    { SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_SE_NW, SPR_JUNIOR_RC_25_DEG_UP_TO_RIGHT_BANK_SE_NW_FRONT },
};

static constexpr uint32_t junior_rc_track_pieces_left_bank[4] = {
    SPR_JUNIOR_RC_LEFT_BANK_SW_NE,
    SPR_JUNIOR_RC_LEFT_BANK_NW_SE,
    SPR_JUNIOR_RC_LEFT_BANK_NE_SW,
    SPR_JUNIOR_RC_LEFT_BANK_SE_NW,
};

static constexpr uint32_t junior_rc_track_pieces_left_quarter_turn_5_tiles_25_deg_up[2][4][5] = {
    {
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_4,
        },
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_4,
        },
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_4,
        },
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_4,
        },
    },
    {
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_4,
        },
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_4,
        },
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_4,
        },
        {
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_0,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_1,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_2,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_3,
            SPR_JUNIOR_RC_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_4,
        },
    },
};

static constexpr CoordsXY junior_rc_left_quarter_turn_5_tiles_25_deg_up_offsets[4][5] = {
    {
        { 0, 6 },
        { 0, 0 },
        { 0, 16 },
        { 16, 0 },
        { 6, 0 },
    },
    {
        { 6, 0 },
        { 0, 0 },
        { 16, 16 },
        { 0, 0 },
        { 0, 6 },
    },
    {
        { 0, 6 },
        { 0, 16 },
        { 16, 0 },
        { 0, 0 },
        { 6, 0 },
    },
    {
        { 6, 0 },
        { 16, 0 },
        { 0, 0 },
        { 0, 16 },
        { 0, 6 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_quarter_turn_5_tiles_25_deg_up[2][4][5] = {
    {
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SW_SE_PART_4,
        },
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NW_SW_PART_4,
        },
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_NE_NW_PART_4,
        },
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_SE_NE_PART_4,
        },
    },
    {
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SW_SE_PART_4,
        },
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NW_SW_PART_4,
        },
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_NE_NW_PART_4,
        },
        {
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_0,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_1,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_2,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_3,
            SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP_CHAIN_SE_NE_PART_4,
        },
    },
};

static constexpr uint32_t junior_rc_track_pieces_s_bend_left[2][4] = {
    {
        SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_0,
        SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_1,
        SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_2,
        SPR_JUNIOR_RC_S_BEND_LEFT_SW_NE_PART_3,
    },
    {
        SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_3,
        SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_2,
        SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_1,
        SPR_JUNIOR_RC_S_BEND_LEFT_SE_NW_PART_0,
    },
};

static constexpr uint32_t junior_rc_track_pieces_s_bend_right[2][4] = {
    {
        SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_0,
        SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_1,
        SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_2,
        SPR_JUNIOR_RC_S_BEND_RIGHT_SW_NE_PART_3,
    },
    {
        SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_3,
        SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_2,
        SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_1,
        SPR_JUNIOR_RC_S_BEND_RIGHT_SE_NW_PART_0,
    },
};

static constexpr uint32_t junior_rc_track_pieces_flat_quarter_turn_3_tiles[4][3] = {
    {
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SW_SE_PART_0,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SW_SE_PART_1,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SW_SE_PART_2,
    },
    {
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NW_SW_PART_0,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NW_SW_PART_1,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NW_SW_PART_2,
    },
    {
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NE_NW_PART_0,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NE_NW_PART_1,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_NE_NW_PART_2,
    },
    {
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SE_NE_PART_0,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SE_NE_PART_1,
        SPR_JUNIOR_RC_QUARTER_TURN_3_TILES_SE_NE_PART_2,
    },
};

static constexpr uint32_t junior_rc_track_pieces_banked_quarter_turn_3_tiles[4][3] = {
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SW_SE_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SW_SE_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SW_SE_PART_2,
    },
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_2,
    },
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NE_NW_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NE_NW_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NE_NW_PART_2,
    },
    {
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_0,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_1,
        SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_2,
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_quarter_turn_3_tiles_25_deg_up[2][4][2] = {
    {
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SW_SE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NW_SW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NE_NW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_NE_NW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_SE_NE_PART_1 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SW_SE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NW_SW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NE_NW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_NE_NW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP_CHAIN_SE_NE_PART_1 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_quarter_turn_3_tiles_25_deg_down[2][4][2] = {
    {
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SW_SE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NW_SW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NE_NW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_NE_NW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_SE_NE_PART_1 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SW_SE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NW_SW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NE_NW_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_NE_NW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_CHAIN_SE_NE_PART_1 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_half_banked_helix_up_small_quarter_tiles[4][3][2] = {
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SW_SE_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SW_SE_PART_2 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_2,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NW_SW_PART_2_2 },
    },
    {
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NE_NW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NE_NW_PART_1 },
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_NE_NW_PART_2 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_0_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_SE_NE_PART_2 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_half_banked_helix_down_small_quarter_tiles[4][3][2] = {
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SW_SE_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SW_SE_PART_2 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_2,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NW_SW_PART_2_2 },
    },
    {
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NE_NW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NE_NW_PART_1 },
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_NE_NW_PART_2 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_0_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL_SE_NE_PART_2 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_half_banked_helix_up_large_quarter_tiles[4][5][2] = {
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_3 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SW_SE_PART_4 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_3 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_4,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NW_SW_PART_4_2 },
    },
    {
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_3 },
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_NE_NW_PART_4 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_0_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_3 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_UP_LARGE_SE_NE_PART_4 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_half_banked_helix_down_large_quarter_tiles[4][5][2] = {
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_3 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SW_SE_PART_4 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_3 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_4,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NW_SW_PART_4_2 },
    },
    {
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_0 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_3 },
        { 0, SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_NE_NW_PART_4 },
    },
    {
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_0,
          SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_0_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_1 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_2 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_3 },
        { SPR_JUNIOR_RC_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE_SE_NE_PART_4 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_brake[4] = {
    SPR_JUNIOR_RC_FLAT_SW_NE_BRAKED,
    SPR_JUNIOR_RC_FLAT_NW_SE_BRAKED,
    SPR_JUNIOR_RC_FLAT_SW_NE_BRAKED,
    SPR_JUNIOR_RC_FLAT_NW_SE_BRAKED,
};

static constexpr uint32_t junior_rc_track_pieces_left_eight_to_diag[4][4] = {
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_N_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_E_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_S_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_W_PART_3,
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_eight_to_diag[4][4] = {
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SW_E_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NW_S_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_NE_W_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_SE_N_PART_3,
    },
};

static constexpr uint32_t junior_rc_track_pieces_left_eight_to_diag_bank[4][4] = {
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_N_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_E_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_S_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_W_PART_3,
    },
};

static constexpr uint32_t junior_rc_track_pieces_right_eight_to_diag_bank[4][4] = {
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SW_E_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NW_S_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_NE_W_PART_3,
    },
    {
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_0,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_1,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_2,
        SPR_JUNIOR_RC_EIGHT_TO_DIAG_BANK_SE_N_PART_3,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_FLAT_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_N_S,
        SPR_JUNIOR_RC_DIAG_FLAT_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_CHAIN_S_N,
    },
    {
        SPR_WATER_RC_DIAG_FLAT_CHAIN_W_E,
        SPR_WATER_RC_DIAG_FLAT_CHAIN_N_S,
        SPR_WATER_RC_DIAG_FLAT_CHAIN_E_W,
        SPR_WATER_RC_DIAG_FLAT_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_up[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_N_S,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_S_N,
    },
    {
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_W_E,
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_N_S,
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_E_W,
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat_to_25_deg_up[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_N_S,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_S_N,
    },
    {
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_W_E,
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_N_S,
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_E_W,
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat_to_60_deg_up[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_N_S,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_up_to_flat[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_N_S,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_S_N,
    },
    {
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_W_E,
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_N_S,
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_E_W,
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_60_deg_up_to_flat[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_N_S,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_down[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_S_N,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_CHAIN_N_S,
    },
    {
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_E_W,
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_S_N,
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_W_E,
        SPR_WATER_RC_DIAG_25_DEG_UP_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat_to_25_deg_down[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_S_N,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_N_S,
    },
    {
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_E_W,
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_S_N,
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_W_E,
        SPR_WATER_RC_DIAG_25_DEG_UP_TO_FLAT_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat_to_60_deg_down[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_S_N,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_FLAT_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_down_to_flat[3][4] = {
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_S_N,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_N_S,
    },
    {
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_E_W,
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_S_N,
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_W_E,
        SPR_WATER_RC_DIAG_FLAT_TO_25_DEG_UP_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_60_deg_down_to_flat[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_S_N,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_FLAT_TO_60_DEG_UP_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat_to_left_bank[4] = {
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_N_S,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_flat_to_right_bank[4] = {
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_N_S,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_right_bank_to_flat[4] = {
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_S_N,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_diag_left_bank_to_flat[4] = {
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_S_N,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_diag_left_bank_to_25_deg_up[4] = {
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_W_E,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_N_S,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_E_W,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_right_bank_to_25_deg_up[4] = {
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_W_E,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_N_S,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_E_W,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_up_to_left_bank[4] = {
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_N_S,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_up_to_right_bank[4] = {
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_N_S,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_right_bank_to_25_deg_down[4] = {
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_S_N,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_diag_left_bank_to_25_deg_down[4] = {
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_S_N,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_down_to_right_bank[4] = {
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_E_W,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_S_N,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_W_E,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_down_to_left_bank[4] = {
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_E_W,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_S_N,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_W_E,
    SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_diag_left_bank[4] = {
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_N_S,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_S_N,
};

static constexpr uint32_t junior_rc_track_pieces_diag_right_bank[4] = {
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_E_W,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_S_N,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_W_E,
    SPR_JUNIOR_RC_DIAG_LEFT_BANK_N_S,
};

static constexpr uint32_t junior_rc_track_pieces_flat_to_60_deg_up[2][4][2] = {
    {
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_SW_NE, 0 },
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_NW_SE, SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_NE_SW, SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_SE_NW, 0 },
    },
    {
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_CHAIN_SW_NE, 0 },
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_CHAIN_NW_SE, SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_CHAIN_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_CHAIN_NE_SW, SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_CHAIN_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_FLAT_TO_60_DEG_UP_CHAIN_SE_NW, 0 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_60_deg_up_to_flat[2][4][2] = {
    {
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_SW_NE, 0 },
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_NW_SE, SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_NE_SW, SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_SE_NW, 0 },
    },
    {
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_CHAIN_SW_NE, 0 },
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_CHAIN_NW_SE, SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_CHAIN_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_CHAIN_NE_SW, SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_CHAIN_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_UP_TO_FLAT_CHAIN_SE_NW, 0 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_60_deg_up[2][4] = {
    {
        SPR_JUNIOR_RC_60_DEG_SW_NE,
        SPR_JUNIOR_RC_60_DEG_NW_SE,
        SPR_JUNIOR_RC_60_DEG_NE_SW,
        SPR_JUNIOR_RC_60_DEG_SE_NW,
    },
    {
        SPR_JUNIOR_RC_60_DEG_CHAIN_SW_NE,
        SPR_JUNIOR_RC_60_DEG_CHAIN_NW_SE,
        SPR_JUNIOR_RC_60_DEG_CHAIN_NE_SW,
        SPR_JUNIOR_RC_60_DEG_CHAIN_SE_NW,
    },
};

static constexpr uint32_t junior_rc_track_pieces_25_deg_up_to_60_deg_up[2][4][2] = {
    {
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_SW_NE, 0 },
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NW_SE, SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NE_SW, SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_SE_NW, 0 },
    },
    {
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_SW_NE, 0 },
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NW_SE, SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NE_SW, SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_25_DEG_TO_60_DEG_UP_CHAIN_SE_NW, 0 },
    },
};

static constexpr uint32_t junior_rc_track_pieces_60_deg_up_to_25_deg_up[2][4][2] = {
    {
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_SW_NE, 0 },
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NW_SE, SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NE_SW, SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_SE_NW, 0 },
    },
    {
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_SW_NE, 0 },
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NW_SE, SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NW_SE_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NE_SW, SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_NE_SW_PART_0_2 },
        { SPR_JUNIOR_RC_60_DEG_TO_25_DEG_UP_CHAIN_SE_NW, 0 },
    }
};

static constexpr uint32_t junior_rc_track_pieces_diag_60_deg_up[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_N_S,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_60_deg_down[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_S_N,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_up_to_60_deg_up[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_N_S,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_60_deg_up_to_25_deg_up[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_N_S,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_S_N,
    },
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_N_S,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_S_N,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_25_deg_down_to_60_deg_down[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_S_N,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_60_DEG_UP_TO_25_DEG_UP_CHAIN_N_S,
    },
};

static constexpr uint32_t junior_rc_track_pieces_diag_60_deg_down_to_25_deg_down[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_S_N,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_N_S,
    },
    {
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_E_W,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_S_N,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_W_E,
        SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_60_DEG_UP_CHAIN_N_S,
    },
};

static constexpr const uint32_t junior_rc_track_pieces_diag_brakes[4] = {
    SPR_JUNIOR_RC_DIAG_BRAKES_E_W,
    SPR_JUNIOR_RC_DIAG_BRAKES_N_S,
    SPR_JUNIOR_RC_DIAG_BRAKES_E_W,
    SPR_JUNIOR_RC_DIAG_BRAKES_N_S,
};

static constexpr const uint32_t junior_rc_track_pieces_diag_blockbrakes[2][4] = {
    {
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_E_W_OPEN,
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_N_S_OPEN,
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_E_W_OPEN,
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_N_S_OPEN,
    },
    {
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_E_W_CLOSED,
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_N_S_CLOSED,
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_E_W_CLOSED,
        SPR_JUNIOR_RC_DIAG_BLOCKBRAKES_N_S_CLOSED,
    },
};

template<JuniorRCSubType TSubType> constexpr uint8_t JuniorRCGetSubTypeOffset(const TrackElement& trackElement)
{
    return trackElement.HasChain() ? EnumValue(TSubType) : 0;
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_flat[subTypeOffset][direction]);
    PaintAddImageAsParentRotated(session, direction, imageId, { 0, 6, height }, { 32, 20, 1 });
    PaintUtilPushTunnelRotated(session, direction, height, TunnelGroup::Standard, TunnelSubType::Flat);

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintStation(
    PaintSession& session, const Ride& ride, [[maybe_unused]] uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId imageId;

    bool isBraked = trackElement.IsBrakeClosed();
    auto stationObj = ride.GetStationObject();

    if (direction == 0 || direction == 2)
    {
        if (stationObj != nullptr && !(stationObj->Flags & STATION_OBJECT_FLAGS::NO_PLATFORMS))
        {
            // height -= 2 (height - 2)
            imageId = GetStationColourScheme(session, trackElement).WithIndex(SPR_STATION_BASE_B_SW_NE);
            PaintAddImageAsParent(session, imageId, { 0, 0, height - 2 }, { { 0, 2, height }, { 32, 28, 1 } });
        }

        // height += 2 (height)
        if (trackElement.GetTrackType() == TrackElemType::EndStation && TSubType == JuniorRCSubType::Junior)
        {
            imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_block_brake[isBraked][direction]);
        }
        else
        {
            imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_station[false][direction]);
        }
        PaintAddImageAsChild(session, imageId, { 0, 6, height }, { { 0, 0, height }, { 32, 20, 1 } });
    }
    else if (direction == 1 || direction == 3)
    {
        if (stationObj != nullptr && !(stationObj->Flags & STATION_OBJECT_FLAGS::NO_PLATFORMS))
        {
            // height -= 2 (height - 2)
            imageId = GetStationColourScheme(session, trackElement).WithIndex(SPR_STATION_BASE_B_NW_SE);
            PaintAddImageAsParent(session, imageId, { 0, 0, height - 2 }, { { 2, 0, height }, { 28, 32, 1 } });
        }

        // height += 2 (height)
        if (trackElement.GetTrackType() == TrackElemType::EndStation && TSubType == JuniorRCSubType::Junior)
        {
            imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_block_brake[isBraked][direction]);
        }
        else
        {
            imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_station[false][direction]);
        }
        PaintAddImageAsChild(session, imageId, { 6, 0, height }, { { 0, 0, height }, { 20, 32, 1 } });
    }

    DrawSupportsSideBySide(session, direction, height, session.SupportColours, MetalSupportType::Boxed);
    PaintUtilPushTunnelRotated(session, direction, height, TunnelGroup::Square, TunnelSubType::Flat);

    TrackPaintUtilDrawStation(session, ride, direction, height, trackElement);

    PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrack25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up[subTypeOffset][direction]);
    PaintAddImageAsParentRotated(session, direction, imageId, { 0, 6, height }, { 32, 20, 1 });

    int8_t tunnelHeights[4] = { -8, 8, 8, -8 };
    TunnelSubType tunnelType[4] = { TunnelSubType::SlopeStart, TunnelSubType::SlopeEnd, TunnelSubType::SlopeEnd,
                                    TunnelSubType::SlopeStart };
    PaintUtilPushTunnelRotated(
        session, direction, height + tunnelHeights[direction], TunnelGroup::Standard, tunnelType[direction]);

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 8, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackFlatTo25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_25_deg_up[subTypeOffset][direction]);

    PaintAddImageAsParentRotated(session, direction, imageId, { 0, 6, height }, { 32, 20, 1 });
    if (direction == 0 || direction == 3)
    {
        PaintUtilPushTunnelRotated(session, direction, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintUtilPushTunnelRotated(session, direction, height, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        uint16_t ax = (direction == 0) ? 5 : 3;
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, ax, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrack25DegUpToFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_flat[subTypeOffset][direction]);
    PaintAddImageAsParentRotated(session, direction, imageId, { 0, 6, height }, { 32, 20, 1 });

    TunnelSubType tunnelType;
    int16_t tunnelHeight;
    if (direction == 1 || direction == 2)
    {
        tunnelType = TunnelSubType::FlatTo25Deg;
        tunnelHeight = height + 8;
    }
    else
    {
        tunnelType = TunnelSubType::Flat;
        tunnelHeight = height - 8;
    }

    if (direction & 1)
    {
        PaintUtilPushTunnelRight(session, tunnelHeight, TunnelGroup::Standard, tunnelType);
    }
    else
    {
        PaintUtilPushTunnelLeft(session, tunnelHeight, TunnelGroup::Standard, tunnelType);
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 6, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 40);
}

static constexpr int8_t junior_rc_track_right_quarter_turn_5_tiles_support_height_offset[][7] = {
    { 0, 0, 0, 0, 0, 0, -1 },
    { -1, 0, 0, 0, 0, 0, 0 },
    { 0 },
    { 0, 0, 0, 0, 0, 0, 0 },
};

static void JuniorRCRightQuarterTurn5TilesPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilRightQuarterTurn5TilesPaint(
        session, 1, height, direction, trackSequence, session.TrackColours, junior_rc_track_pieces_flat_quarter_turn_5_tiles,
        kDefaultRightQuarterTurn5TilesOffsets, kDefaultRightQuarterTurn5TilesBoundLengths,
        kDefaultRightQuarterTurn5TilesBoundOffsets);

    int32_t supportHeight = height + junior_rc_track_right_quarter_turn_5_tiles_support_height_offset[direction][trackSequence];
    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, supportHeight, session.SupportColours);
            break;
        case 6:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 0, supportHeight,
                session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 0 && trackSequence == 6)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 1 && trackSequence == 6)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    switch (trackSequence)
    {
        case 0:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide,
                        PaintSegment::rightCorner),
                    direction),
                0xFFFF, 0);
            break;
        case 2:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide,
                        PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::topRightSide),
                    direction),
                0xFFFF, 0);
            break;
        case 3:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::centre),
                    direction),
                0xFFFF, 0);
            break;
        case 5:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
                        PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide),
                    direction),
                0xFFFF, 0);
            break;
        case 6:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide,
                        PaintSegment::leftCorner),
                    direction),
                0xFFFF, 0);
            break;
    }

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

static constexpr uint8_t junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[] = {
    6, 4, 5, 3, 1, 2, 0,
};

/* rct2: 0x0051917A */
static void JuniorRCLeftQuarterTurn5TilesPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[trackSequence];
    JuniorRCRightQuarterTurn5TilesPaintSetup(
        session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType);
}

/**
 * rct2: 0x008AAFC0, 0x00521593, 0x005216A1, 0x005217AF, 0x00521884
 */
static void JuniorRCFlatToLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_left_bank[direction][0]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } });

        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } });

        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (junior_rc_track_pieces_flat_to_left_bank[direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_left_bank[direction][1]);

        if (direction & 1)
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } });
        }
        else
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } });
        }
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/**
 * rct2: 0x008AAFD0, 0x00521959, 0x00521A2E, 0x00521B03, 0x00521C11
 */
static void JuniorRCFlatToRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_right_bank[direction][0]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } });

        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } });

        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (junior_rc_track_pieces_flat_to_right_bank[direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_right_bank[direction][1]);

        if (direction & 1)
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } });
        }
        else
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } });
        }
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

static void JuniorRCLeftBankToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCFlatToRightBankPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static void JuniorRCRightBankToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCFlatToLeftBankPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static constexpr CoordsXY junior_rc_banked_right_quarter_turn_5_tiles_bound_lengths[4][5] = {
    {
        { 32, 20 },
        { 32, 16 },
        { 16, 16 },
        { 16, 32 },
        { 20, 32 },
    },
    {
        { 20, 32 },
        { 16, 32 },
        { 16, 16 },
        { 32, 16 },
        { 32, 20 },
    },
    {
        { 32, 1 },
        { 32, 16 },
        { 16, 16 },
        { 16, 32 },
        { 1, 32 },
    },
    {
        { 20, 32 },
        { 16, 32 },
        { 16, 16 },
        { 32, 16 },
        { 32, 20 },
    },
};

static constexpr CoordsXYZ junior_rc_banked_right_quarter_turn_5_tiles_bound_offsets[4][5] = {
    {
        { 0, 6, 0 },
        { 0, 16, 0 },
        { 0, 0, 0 },
        { 16, 0, 0 },
        { 6, 0, 0 },
    },
    {
        { 6, 0, 0 },
        { 16, 0, 0 },
        { 0, 16, 0 },
        { 0, 0, 0 },
        { 0, 6, 0 },
    },
    {
        { 0, 27, 0 },
        { 0, 0, 27 },
        { 16, 16, 27 },
        { 0, 0, 27 },
        { 27, 0, 0 },
    },
    {
        { 6, 0, 0 },
        { 0, 0, 0 },
        { 16, 0, 0 },
        { 0, 16, 0 },
        { 0, 6, 0 },
    },
};

/* rct2: 0x008AB010, 0x0052304C */
static void JuniorRCBankedRightQuarterTurn5TilesPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    uint8_t thickness = 1;
    if (direction == 2 && (trackSequence == 0 || trackSequence == 6))
    {
        thickness = 26;
    }
    TrackPaintUtilRightQuarterTurn5TilesPaint(
        session, thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_banked_quarter_turn_5_tiles, nullptr, junior_rc_banked_right_quarter_turn_5_tiles_bound_lengths,
        junior_rc_banked_right_quarter_turn_5_tiles_bound_offsets);

    if (direction == 1 && trackSequence == 6)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_NW_SW_PART_4_2);
        PaintAddImageAsParent(session, imageId, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } });
    }
    else if (direction == 3 && trackSequence == 0)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_BANKED_QUARTER_TURN_5_TILES_SE_NE_PART_0_2);
        PaintAddImageAsParent(session, imageId, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } });
    }

    int32_t supportHeight = height;
    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, supportHeight, session.SupportColours);
            break;
        case 6:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 0, supportHeight,
                session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 0 && trackSequence == 6)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 1 && trackSequence == 6)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    switch (trackSequence)
    {
        case 0:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide,
                        PaintSegment::rightCorner),
                    direction),
                0xFFFF, 0);
            break;
        case 2:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide,
                        PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::topRightSide),
                    direction),
                0xFFFF, 0);
            break;
        case 3:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::centre),
                    direction),
                0xFFFF, 0);
            break;
        case 5:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
                        PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide),
                    direction),
                0xFFFF, 0);
            break;
        case 6:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide,
                        PaintSegment::leftCorner),
                    direction),
                0xFFFF, 0);
            break;
    }

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/* rct2: 0x008AB000 */
static void JuniorRCBankedLeftQuarterTurn5TilesPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[trackSequence];
    JuniorRCBankedRightQuarterTurn5TilesPaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/**
 * rct2: 0x008AB020, 0x00522073, 0x00522182, 0x00522291, 0x00522367
 */
static void JuniorRCLeftBankTo25DegUpPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_left_banked_to_25_deg_up[direction][0]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } });
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } });
    }

    if (junior_rc_track_pieces_left_banked_to_25_deg_up[direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_left_banked_to_25_deg_up[direction][1]);

        if (direction & 1)
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 34 } });
        }
        else
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 34 } });
        }
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 3, height, session.SupportColours);
    }

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
            break;
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

/**
 * rct2: 0x008AB030, 0x0052243D, 0x00522513, 0x005225E9, 0x005226F8
 */
static void JuniorRCRightBankTo25DegUpPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_right_banked_to_25_deg_up[direction][0]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } });
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } });
    }

    if (junior_rc_track_pieces_right_banked_to_25_deg_up[direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_right_banked_to_25_deg_up[direction][1]);

        if (direction & 1)
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 34 } });
        }
        else
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 34 } });
        }
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 3, height, session.SupportColours);
    }

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
            break;
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

/**
 * rct2: 0x008AB040, 0x00522807, 0x0052291A, 0x00522A2D, 0x00522B07
 */
static void JuniorRC25DegUpToLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    TunnelSubType tunnelType;
    int16_t tunnelHeight;
    if (direction == 1 || direction == 2)
    {
        tunnelType = TunnelSubType::FlatTo25Deg;
        tunnelHeight = height + 8;
    }
    else
    {
        tunnelType = TunnelSubType::Flat;
        tunnelHeight = height - 8;
    }

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_left_bank[direction][0]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } });

        PaintUtilPushTunnelRight(session, tunnelHeight, TunnelGroup::Standard, tunnelType);
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } });

        PaintUtilPushTunnelLeft(session, tunnelHeight, TunnelGroup::Standard, tunnelType);
    }

    if (junior_rc_track_pieces_25_deg_up_to_left_bank[direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_left_bank[direction][1]);

        if (direction & 1)
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 34 } });
        }
        else
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 34 } });
        }
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 6, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 40);
}

/**
 * rct2: 0x008AB050, 0x00522BE1, 0x00522CBB, 0x00522D95, 0x00522EA8
 */
static void JuniorRC25DegUpToRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    TunnelSubType tunnelType;
    int16_t tunnelHeight;
    if (direction == 1 || direction == 2)
    {
        tunnelType = TunnelSubType::FlatTo25Deg;
        tunnelHeight = height + 8;
    }
    else
    {
        tunnelType = TunnelSubType::Flat;
        tunnelHeight = height - 8;
    }

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_right_bank[direction][0]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } });

        PaintUtilPushTunnelRight(session, tunnelHeight, TunnelGroup::Standard, tunnelType);
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } });

        PaintUtilPushTunnelLeft(session, tunnelHeight, TunnelGroup::Standard, tunnelType);
    }

    if (junior_rc_track_pieces_25_deg_up_to_right_bank[direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_right_bank[direction][1]);

        if (direction & 1)
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 34 } });
        }
        else
        {
            PaintAddImageAsParent(session, image_id, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 34 } });
        }
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 6, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 40);
}

/**
 * rct2: 0x008AB060
 */
static void JuniorRCLeftBankTo25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRC25DegUpToRightBankPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

/**
 * rct2: 0x008AB070
 */
static void JuniorRCRightBankTo25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRC25DegUpToLeftBankPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

/**
 * rct2: 0x008AB080
 */
static void JuniorRC25DegDownToLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCRightBankTo25DegUpPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

/**
 * rct2: 0x008AB090
 */
static void JuniorRC25DegDownToRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCLeftBankTo25DegUpPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static constexpr CoordsXYZ junior_rc_left_bank_bound_lengths[4] = {
    { 32, 1, 26 },
    { 1, 32, 26 },
    { 32, 20, 1 },
    { 20, 32, 1 },
};

static constexpr CoordsXY junior_rc_left_bank_bound_offsets[4] = {
    { 0, 27 },
    { 27, 0 },
    { 0, 6 },
    { 6, 0 },
};

/**
 * rct2: 0x008AB0A0, 0x00521D1F, 0x00521DF4, 0x00521EC9, 0x00521F9E
 */
static void JuniorRCLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_left_bank[direction]);
    PaintAddImageAsParent(
        session, image_id, { 0, 0, height },
        { { junior_rc_left_bank_bound_offsets[direction], height }, junior_rc_left_bank_bound_lengths[direction] });

    if (direction & 1)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/**
 * rct2: 0x008AB0B0
 */
static void JuniorRCRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCLeftBankPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static void JuniorRCPaintTrackLeftQuarterTurn5Tiles25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);
    TrackPaintUtilRightQuarterTurn5TilesPaint(
        session, 1, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_left_quarter_turn_5_tiles_25_deg_up[subTypeOffset],
        junior_rc_left_quarter_turn_5_tiles_25_deg_up_offsets, kDefaultRightQuarterTurn5TilesBoundLengths, nullptr);

    static constexpr uint8_t supportSpecial[4] = { 8, 8, 8, 3 };
    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, (direction == 0 || direction == 3) ? 10 : 8,
                height, session.SupportColours);
            break;
        case 6:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionPrev(direction), supportSpecial[direction],
                height, session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }
    if (direction == 2 && trackSequence == 6)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }
    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }
    if (direction == 3 && trackSequence == 6)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    switch (trackSequence)
    {
        case 0:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide,
                        PaintSegment::topCorner),
                    direction),
                0xFFFF, 0);
            break;
        case 2:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topCorner, PaintSegment::leftCorner,
                        PaintSegment::topLeftSide, PaintSegment::topRightSide),
                    direction),
                0xFFFF, 0);
            break;
        case 3:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::rightCorner, PaintSegment::topRightSide,
                        PaintSegment::centre),
                    direction),
                0xFFFF, 0);
            break;
        case 5:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
                        PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide),
                    direction),
                0xFFFF, 0);
            break;
        case 6:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide,
                        PaintSegment::bottomCorner),
                    direction),
                0xFFFF, 0);
            break;
    }
    if (trackSequence == 3)
    {
        PaintUtilSetGeneralSupportHeight(session, height + 64);
    }
    else
    {
        PaintUtilSetGeneralSupportHeight(session, height + 72);
    }
}

static void JuniorRCPaintTrackRightQuarterTurn5Tiles25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);
    TrackPaintUtilRightQuarterTurn5TilesPaint(
        session, 1, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_quarter_turn_5_tiles_25_deg_up[subTypeOffset], kDefaultRightQuarterTurn5TilesOffsets,
        kDefaultRightQuarterTurn5TilesBoundLengths, nullptr);

    static constexpr uint8_t supportSpecial[4] = { 11, 8, 8, 7 };
    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, supportSpecial[direction], height,
                session.SupportColours);
            break;
        case 6:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 8, height,
                session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }
    if (direction == 0 && trackSequence == 6)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }
    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }
    if (direction == 1 && trackSequence == 6)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    switch (trackSequence)
    {
        case 0:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide,
                        PaintSegment::rightCorner),
                    direction),
                0xFFFF, 0);
            break;
        case 2:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide,
                        PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::topRightSide),
                    direction),
                0xFFFF, 0);
            break;
        case 3:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::centre),
                    direction),
                0xFFFF, 0);
            break;
        case 5:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
                        PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide),
                    direction),
                0xFFFF, 0);
            break;
        case 6:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide,
                        PaintSegment::leftCorner),
                    direction),
                0xFFFF, 0);
            break;
    }
    if (trackSequence == 3)
    {
        PaintUtilSetGeneralSupportHeight(session, height + 64);
    }
    else
    {
        PaintUtilSetGeneralSupportHeight(session, height + 72);
    }
}

/* rct2: 0x008AAE30, 0x0051AA42, 0x0051AA68, 0x0051AA8C, 0x0051AAB0 */
static void JuniorRCLeftQuarterTurn5Tiles25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrackRightQuarterTurn5Tiles25DegUp(
        session, ride, junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[trackSequence], (direction + 1) & 3, height,
        trackElement, supportType);
}

/* rct2: 0x008AAE40, 0x0051AAD4, 0x0051AE04, 0x0051B10E, 0x0051B3F4 */
static void JuniorRCRightQuarterTurn5Tiles25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrackLeftQuarterTurn5Tiles25DegUp(
        session, ride, junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[trackSequence], (direction - 1) & 3, height,
        trackElement, supportType);
}

/* rct2: 0x008AAE50, 0x0051B6FE, 0x0051B946, 0x0051BB8E, 0x0051BBA8 */
static void JuniorRCSBendLeftPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (direction == 2 || direction == 3)
    {
        trackSequence = 3 - trackSequence;
    }

    static constexpr CoordsXY offsetList[] = {
        { 0, 6 },
        { 0, 0 },
        { 0, 6 },
        { 0, 6 },
    };

    static constexpr CoordsXY boundsList[] = {
        { 32, 20 },
        { 32, 26 },
        { 32, 26 },
        { 32, 20 },
    };

    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_s_bend_left[(direction & 1)][trackSequence]);
    CoordsXY offset = offsetList[trackSequence];
    CoordsXY bounds = boundsList[trackSequence];
    if (direction == 0 || direction == 2)
    {
        PaintAddImageAsParent(session, imageId, { offset.x, offset.y, height }, { bounds.x, bounds.y, 1 });
    }
    else
    {
        PaintAddImageAsParent(session, imageId, { offset.y, offset.x, height }, { bounds.y, bounds.x, 1 });
    }

    if (direction == 0 || direction == 2)
    {
        if (trackSequence == 0)
        {
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
        }
    }
    else
    {
        if (trackSequence == 3)
        {
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
        }
    }
    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 1:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::TopLeftSide, direction & 1, 0, height, session.SupportColours);
            break;
        case 3:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::topCorner);
            break;
        case 1:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner,
                PaintSegment::topLeftSide, PaintSegment::topCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner,
                PaintSegment::bottomRightSide, PaintSegment::rightCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, (direction & 1)), 0xFFFF, 0);

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/* rct2: 0x008AAE60, 0x0051BBC0, 0x0051BE06, 0x0051C04E, 0x0051C068 */
static void JuniorRCSBendRightPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (direction == 2 || direction == 3)
    {
        trackSequence = 3 - trackSequence;
    }

    static constexpr CoordsXY offsetList[] = {
        { 0, 6 },
        { 0, 6 },
        { 0, 0 },
        { 0, 6 },
    };

    static constexpr CoordsXY boundsList[] = {
        { 32, 20 },
        { 32, 26 },
        { 32, 26 },
        { 32, 20 },
    };

    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_s_bend_right[direction & 1][trackSequence]);
    CoordsXY offset = offsetList[trackSequence];
    CoordsXY bounds = boundsList[trackSequence];
    if (direction == 0 || direction == 2)
    {
        PaintAddImageAsParent(session, imageId, { offset.x, offset.y, height }, { bounds.x, bounds.y, 1 });
    }
    else
    {
        PaintAddImageAsParent(session, imageId, { offset.y, offset.x, height }, { bounds.y, bounds.x, 1 });
    }

    if (direction == 0 || direction == 2)
    {
        if (trackSequence == 0)
        {
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
        }
    }
    else
    {
        if (trackSequence == 3)
        {
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
        }
    }
    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 1:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::BottomRightSide, direction & 1, 0, height,
                session.SupportColours);
            break;
        case 3:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner);
            break;
        case 1:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner,
                PaintSegment::bottomRightSide, PaintSegment::rightCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner,
                PaintSegment::topLeftSide, PaintSegment::topCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, (direction & 1)), 0xFFFF, 0);

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AAEB0, 0x0051C0E0, 0x0051C2C1, 0x0051C47F, 0x0051C61D */
static void JuniorRCRightQuarterTurn3TilesPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilRightQuarterTurn3TilesPaint(
        session, 1, height, direction, trackSequence, session.TrackColours, junior_rc_track_pieces_flat_quarter_turn_3_tiles,
        defaultRightQuarterTurn3TilesOffsets, defaultRightQuarterTurn3TilesBoundLengths, nullptr);
    TrackPaintUtilRightQuarterTurn3TilesTunnel(
        session, TunnelGroup::Standard, TunnelSubType::Flat, height, direction, trackSequence);

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 3:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionPrev(direction), 0, height,
                session.SupportColours);
            break;
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide, PaintSegment::bottomCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AAEA0 */
static void JuniorRCLeftQuarterTurn3TilesPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence];
    JuniorRCRightQuarterTurn3TilesPaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

static constexpr CoordsXY junior_rc_right_quarter_turn_3_tiles_bank_bound_lengths[4][3] = {
    {
        { 32, 20 },
        { 16, 16 },
        { 20, 32 },
    },
    {
        { 20, 32 },
        { 16, 16 },
        { 32, 20 },
    },
    {
        { 32, 1 },
        { 16, 16 },
        { 1, 32 },
    },
    {
        { 20, 32 },
        { 16, 16 },
        { 32, 20 },
    },
};

static constexpr CoordsXYZ junior_rc_right_quarter_turn_3_tiles_bank_offsets[4][3] = {
    {
        { 0, 6, 0 },
        { 16, 16, 0 },
        { 6, 0, 0 },
    },
    {
        { 6, 0, 0 },
        { 16, 0, 0 },
        { 0, 6, 0 },
    },
    {
        { 0, 27, 0 },
        { 0, 0, 27 },
        { 27, 0, 0 },
    },
    {
        { 6, 0, 0 },
        { 0, 16, 0 },
        { 0, 6, 0 },
    },
};

/** rct2: 0x008AA0D0, 0x00523EA0, 0x005240CC, 0x0052430F, 0x00524500*/
static void JuniorRCRightQuarterTurn3TilesBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    static constexpr uint8_t thickness[4][4] = {
        { 1, 1, 1, 1 },
        { 1, 1, 1, 1 },
        { 26, 1, 1, 26 },
        { 1, 1, 1, 1 },
    };

    TrackPaintUtilRightQuarterTurn3TilesPaint(
        session, thickness[direction][trackSequence], height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_banked_quarter_turn_3_tiles, nullptr, junior_rc_right_quarter_turn_3_tiles_bank_bound_lengths,
        junior_rc_right_quarter_turn_3_tiles_bank_offsets);
    TrackPaintUtilRightQuarterTurn3TilesTunnel(
        session, TunnelGroup::Standard, TunnelSubType::Flat, height, direction, trackSequence);

    if (direction == 1 && trackSequence == 3)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_NW_SW_PART_2_2);
        PaintAddImageAsParent(session, imageId, { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } });
    }
    else if (direction == 3 && trackSequence == 0)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_BANKED_QUARTER_TURN_3_TILES_SE_NE_PART_0_2);
        PaintAddImageAsParent(session, imageId, { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } });
    }

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 3:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 0, height,
                session.SupportColours);
            break;
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide, PaintSegment::bottomCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

static void JuniorRCPaintTrackRightQuarterTurn3Tiles25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);
    auto imageId = ImageId(0);
    CoordsXY offset;
    BoundBoxXY bb;

    switch (trackSequence)
    {
        case 0:
            imageId = session.TrackColours.WithIndex(
                junior_rc_track_pieces_right_quarter_turn_3_tiles_25_deg_up[subTypeOffset][direction][0]);
            offset = defaultRightQuarterTurn3TilesOffsets[direction][0];
            bb.length = defaultRightQuarterTurn3TilesBoundLengths[direction][0];
            bb.offset = offset;
            break;
        case 3:
            imageId = session.TrackColours.WithIndex(
                junior_rc_track_pieces_right_quarter_turn_3_tiles_25_deg_up[subTypeOffset][direction][1]);
            offset = defaultRightQuarterTurn3TilesOffsets[direction][2];
            bb.length = defaultRightQuarterTurn3TilesBoundLengths[direction][2];
            bb.offset = offset;
            break;
    }
    if (imageId.GetIndex() != 0)
    {
        PaintAddImageAsParent(session, imageId, { offset, height }, { { bb.offset, height }, { bb.length, 1 } });
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }

    if (direction == 0 && trackSequence == 3)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    if (direction == 1 && trackSequence == 3)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 8, height, session.SupportColours);
            break;
        case 3:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 8, height,
                session.SupportColours);
            break;
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);

    if (trackSequence == 0 || trackSequence == 3)
        PaintUtilSetGeneralSupportHeight(session, height + 72);
    else
        PaintUtilSetGeneralSupportHeight(session, height + 56);
}

static void JuniorRCPaintTrackRightQuarterTurn3Tiles25DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);
    auto imageId = ImageId(0);
    CoordsXY offset;
    BoundBoxXY bb;

    switch (trackSequence)
    {
        case 0:
            imageId = session.TrackColours.WithIndex(
                junior_rc_track_pieces_right_quarter_turn_3_tiles_25_deg_down[subTypeOffset][direction][0]);
            offset = defaultRightQuarterTurn3TilesOffsets[direction][0];
            bb.length = defaultRightQuarterTurn3TilesBoundLengths[direction][0];
            bb.offset = offset;
            break;
        case 3:
            imageId = session.TrackColours.WithIndex(
                junior_rc_track_pieces_right_quarter_turn_3_tiles_25_deg_down[subTypeOffset][direction][1]);
            offset = defaultRightQuarterTurn3TilesOffsets[direction][2];
            bb.length = defaultRightQuarterTurn3TilesBoundLengths[direction][2];
            bb.offset = offset;
            break;
    }
    if (imageId.GetIndex() != 0)
    {
        PaintAddImageAsParent(session, imageId, { offset, height }, { { bb.offset, height }, { bb.length, 1 } });
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    if (direction == 0 && trackSequence == 3)
    {
        PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }

    if (direction == 1 && trackSequence == 3)
    {
        PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
    }

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 8, height, session.SupportColours);
            break;
        case 3:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 8, height,
                session.SupportColours);
            break;
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);

    if (trackSequence == 0 || trackSequence == 3)
        PaintUtilSetGeneralSupportHeight(session, height + 72);
    else
        PaintUtilSetGeneralSupportHeight(session, height + 56);
}

/** rct2: 0x008AA0C0 */
static void JuniorRCLeftQuarterTurn3TilesBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence];
    JuniorRCRightQuarterTurn3TilesBankPaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

static constexpr uint8_t junior_rc_left_quarter_turn_3_tiles_to_right_turn_map[] = {
    3,
    1,
    2,
    0,
};

/** rct2: 0x008AAEC0 */
static void JuniorRCLeftQuarterTurn3Tiles25DegUpPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = junior_rc_left_quarter_turn_3_tiles_to_right_turn_map[trackSequence];
    JuniorRCPaintTrackRightQuarterTurn3Tiles25DegDown(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AAEE0 */
static void JuniorRCLeftQuarterTurn3Tiles25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = junior_rc_left_quarter_turn_3_tiles_to_right_turn_map[trackSequence];
    JuniorRCPaintTrackRightQuarterTurn3Tiles25DegUp(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AB0F0, 0x0052B3A4, 0x0052B5F8, 0x0052B863, 0x0052BA78 */
static void JuniorRCRightHalfBankedHelixUpSmallPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    static constexpr int8_t thickness[2] = { 1, 26 };

    if (trackSequence > 3)
    {
        trackSequence -= 4;
        direction++;
        direction &= 3;
    }
    TrackPaintUtilRightHelixUpSmallQuarterTilesPaint(
        session, thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_half_banked_helix_up_small_quarter_tiles, nullptr,
        defaultRightHelixUpSmallQuarterBoundLengths, defaultRightHelixUpSmallQuarterBoundOffsets);

    if (trackSequence == 0)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 2, height, session.SupportColours);
    }
    else if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 6, height, session.SupportColours);
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 0 && trackSequence == 3)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 1 && trackSequence == 3)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner,
                PaintSegment::bottomRightSide);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomCorner, PaintSegment::bottomRightSide);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide,
                PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB110, 0x0052BD80, 0x0052BFD4, 0x0052C23B, 0x0052C450 */
static void JuniorRCRightHalfBankedHelixDownSmallPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    static constexpr int8_t thickness[2] = { 1, 26 };

    if (trackSequence > 3)
    {
        trackSequence -= 4;
        direction++;
        direction &= 3;
    }
    TrackPaintUtilRightHelixUpSmallQuarterTilesPaint(
        session, thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_half_banked_helix_down_small_quarter_tiles, nullptr,
        defaultRightHelixUpSmallQuarterBoundLengths, defaultRightHelixUpSmallQuarterBoundOffsets);

    if (trackSequence == 0)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 6, height, session.SupportColours);
    }
    else if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 2, height, session.SupportColours);
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 0 && trackSequence == 3)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 1 && trackSequence == 3)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::rightCorner,
                PaintSegment::bottomRightSide);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomCorner, PaintSegment::bottomRightSide);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::topLeftSide,
                PaintSegment::leftCorner);
            break;
    }
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB0E0 */
static void JuniorRCLeftHalfBankedHelixUpSmallPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (trackSequence > 3)
    {
        trackSequence -= 4;
        direction--;
        direction &= 3;
    }
    trackSequence = junior_rc_left_quarter_turn_3_tiles_to_right_turn_map[trackSequence];
    JuniorRCRightHalfBankedHelixDownSmallPaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AB100 */
static void JuniorRCLeftHalfBankedHelixDownSmallPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (trackSequence > 3)
    {
        trackSequence -= 4;
        direction--;
        direction &= 3;
    }
    trackSequence = junior_rc_left_quarter_turn_3_tiles_to_right_turn_map[trackSequence];
    JuniorRCRightHalfBankedHelixUpSmallPaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AB130, 0x0052C7BC, 0x0052CB6B, 0x0052CF32, 0x0052D2B3 */
static void JuniorRCRightHalfBankedHelixUpLargePaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    static constexpr int8_t thickness[2] = { 1, 26 };

    if (trackSequence > 6)
    {
        trackSequence -= 7;
        direction++;
        direction &= 3;
    }
    TrackPaintUtilRightHelixUpLargeQuarterTilesPaint(
        session, thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_half_banked_helix_up_large_quarter_tiles, nullptr,
        defaultRightHelixUpLargeQuarterBoundLengths, defaultRightHelixUpLargeQuarterBoundOffsets);

    if (trackSequence == 0)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 1, height, session.SupportColours);
    }
    else if (trackSequence == 6)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 7, height, session.SupportColours);
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 0 && trackSequence == 6)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 1 && trackSequence == 6)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    switch (trackSequence)
    {
        case 0:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide, PaintSegment::centre,
                        PaintSegment::topRightSide, PaintSegment::rightCorner),
                    direction),
                0xFFFF, 0);
            break;
        case 2:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide,
                        PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::topRightSide),
                    direction),
                0xFFFF, 0);
            break;
        case 3:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::centre),
                    direction),
                0xFFFF, 0);
            break;
        case 5:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
                        PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide),
                    direction),
                0xFFFF, 0);
            break;
        case 6:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide, PaintSegment::centre,
                        PaintSegment::topLeftSide, PaintSegment::leftCorner),
                    direction),
                0xFFFF, 0);
            break;
    }

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB150, 0x0052D778, 0x0052DB27, 0x0052DEEA, 0x0052E26B */
static void JuniorRCRightHalfBankedHelixDownLargePaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    static constexpr int8_t thickness[2] = { 1, 26 };

    if (trackSequence > 6)
    {
        trackSequence -= 7;
        direction++;
        direction &= 3;
    }
    TrackPaintUtilRightHelixUpLargeQuarterTilesPaint(
        session, thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_half_banked_helix_down_large_quarter_tiles, nullptr,
        defaultRightHelixUpLargeQuarterBoundLengths, defaultRightHelixUpLargeQuarterBoundOffsets);

    if (trackSequence == 0)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 7, height, session.SupportColours);
    }
    else if (trackSequence == 6)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, DirectionNext(direction), 1, height, session.SupportColours);
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 0 && trackSequence == 6)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 1 && trackSequence == 6)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height + 8, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    switch (trackSequence)
    {
        case 0:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide, PaintSegment::centre,
                        PaintSegment::topRightSide, PaintSegment::rightCorner),
                    direction),
                0xFFFF, 0);
            break;
        case 2:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide,
                        PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::topRightSide),
                    direction),
                0xFFFF, 0);
            break;
        case 3:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::centre),
                    direction),
                0xFFFF, 0);
            break;
        case 5:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
                        PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide),
                    direction),
                0xFFFF, 0);
            break;
        case 6:
            PaintUtilSetSegmentSupportHeight(
                session,
                PaintUtilRotateSegments(
                    EnumsToFlags(
                        PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide, PaintSegment::centre,
                        PaintSegment::topLeftSide, PaintSegment::leftCorner),
                    direction),
                0xFFFF, 0);
            break;
    }

    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB120 */
static void JuniorRCLeftHalfBankedHelixUpLargePaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (trackSequence > 6)
    {
        trackSequence -= 7;
        direction--;
        direction &= 3;
    }
    trackSequence = junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[trackSequence];
    JuniorRCRightHalfBankedHelixDownLargePaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AB140 */
static void JuniorRCLeftHalfBankedHelixDownLargePaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (trackSequence > 6)
    {
        trackSequence -= 7;
        direction--;
        direction &= 3;
    }
    trackSequence = junior_rc_left_quarter_turn_5_tiles_to_right_turn_map[trackSequence];
    JuniorRCRightHalfBankedHelixUpLargePaintSetup(
        session, ride, trackSequence, (direction + 1) % 4, height, trackElement, supportType);
}

/**
 * rct2: 0x008AAF00, 0x0051851C, 0x005185D8
 */
static void JuniorRCBrakePaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_brake[direction]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 6, 0, height }, { 20, 32, 1 });

        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 6, height }, { 32, 20, 1 });

        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/**
 * rct2: 0x008AB280, 0x00518694, 0x00518759
 */
static void JuniorRCBlockBrakePaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    ImageId image_id;

    bool isBraked = trackElement.IsBrakeClosed();

    image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_block_brake[isBraked][direction]);
    if (direction & 1)
    {
        PaintAddImageAsParent(session, image_id, { 6, 0, height }, { 20, 32, 1 });

        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintAddImageAsParent(session, image_id, { 0, 6, height }, { 32, 20, 1 });

        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AAF80 */
static void JuniorRCLeftEighthToDiagPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilEighthToDiagTilesPaint(
        session, defaultEighthToDiagThickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_left_eight_to_diag, nullptr, defaultLeftEighthToDiagBoundLengths,
        defaultLeftEighthToDiagBoundOffsets);

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 4:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::LeftCorner, DirectionPrev(direction), 0, height,
                session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide);
            break;
        case 1:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner,
                PaintSegment::topLeftSide, PaintSegment::topCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner, PaintSegment::bottomRightSide,
                PaintSegment::rightCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::leftCorner, PaintSegment::topLeftSide);
            break;
        case 4:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::topLeftSide,
                PaintSegment::bottomCorner, PaintSegment::bottomRightSide);
            break;
    }

    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AAF90 */
static void JuniorRCRightEighthToDiagPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilEighthToDiagTilesPaint(
        session, defaultEighthToDiagThickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_eight_to_diag, nullptr, defaultRightEighthToDiagBoundLengths,
        defaultRightEighthToDiagBoundOffsets);

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 4:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::BottomCorner, DirectionNext(direction), 0, height,
                session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide);
            break;
        case 1:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner,
                PaintSegment::bottomRightSide, PaintSegment::rightCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner, PaintSegment::topLeftSide,
                PaintSegment::topCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomCorner, PaintSegment::bottomRightSide);
            break;
        case 4:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner,
                PaintSegment::topLeftSide, PaintSegment::bottomRightSide);
            break;
    }

    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AAFA0 */
static void JuniorRCLeftEighthToOrthogonalPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence];
    JuniorRCRightEighthToDiagPaintSetup(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AAFB0 */
static void JuniorRCRightEighthToOrthogonalPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence];
    JuniorRCLeftEighthToDiagPaintSetup(session, ride, trackSequence, (direction + 3) % 4, height, trackElement, supportType);
}

static constexpr CoordsXY junior_rc_left_eighth_to_diag_bank_bound_lengths[4][4] = {
    {
        { 32, 1 },
        { 32, 16 },
        { 16, 16 },
        { 16, 16 },
    },
    {
        { 1, 32 },
        { 16, 34 },
        { 16, 16 },
        { 18, 16 },
    },
    {
        { 32, 20 },
        { 32, 16 },
        { 16, 16 },
        { 16, 16 },
    },
    {
        { 20, 32 },
        { 16, 32 },
        { 16, 16 },
        { 16, 16 },
    },
};

static constexpr CoordsXYZ junior_rc_left_eighth_to_diag_bank_bound_offsets[4][4] = {
    {
        { 0, 27, 0 },
        { 0, 0, 0 },
        { 0, 16, 0 },
        { 16, 16, 0 },
    },
    {
        { 27, 0, 0 },
        { 0, 0, 27 },
        { 16, 16, 27 },
        { 16, 0, 27 },
    },
    {
        { 0, 6, 0 },
        { 0, 16, 0 },
        { 16, 0, 0 },
        { 0, 0, 0 },
    },
    {
        { 6, 0, 0 },
        { 16, 0, 0 },
        { 0, 0, 0 },
        { 0, 16, 0 },
    },
};

static constexpr int8_t junior_rc_left_eighth_to_diag_bank_thickness[4][4] = {
    {
        26,
        1,
        1,
        1,
    },
    {
        26,
        0,
        0,
        0,
    },
    {
        1,
        1,
        1,
        1,
    },
    {
        1,
        1,
        1,
        1,
    },
};

/** rct2: 0x008AB160 */
static void JuniorRCLeftEighthToDiagBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilEighthToDiagTilesPaint(
        session, junior_rc_left_eighth_to_diag_bank_thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_left_eight_to_diag_bank, nullptr, junior_rc_left_eighth_to_diag_bank_bound_lengths,
        junior_rc_left_eighth_to_diag_bank_bound_offsets);

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 4:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::BottomCorner, direction, 0, height, session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide);
            break;
        case 1:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner,
                PaintSegment::topLeftSide, PaintSegment::topCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner, PaintSegment::bottomRightSide,
                PaintSegment::rightCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::leftCorner, PaintSegment::topLeftSide);
            break;
        case 4:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::topLeftSide,
                PaintSegment::bottomCorner, PaintSegment::bottomRightSide);
            break;
    }

    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

static constexpr CoordsXY junior_rc_right_eighth_to_diag_bank_bound_lengths[4][4] = {
    {
        { 32, 20 },
        { 16, 16 },
        { 16, 16 },
        { 16, 16 },
    },
    {
        { 20, 32 },
        { 16, 32 },
        { 16, 16 },
        { 16, 16 },
    },
    {
        { 32, 1 },
        { 34, 16 },
        { 28, 28 },
        { 16, 18 },
    },
    {
        { 1, 32 },
        { 16, 32 },
        { 16, 16 },
        { 16, 16 },
    },
};

static constexpr CoordsXYZ junior_rc_right_eighth_to_diag_bank_bound_offsets[4][4] = {
    {
        { 0, 6, 0 },
        { 0, 0, 0 },
        { 0, 0, 0 },
        { 16, 0, 0 },
    },
    {
        { 6, 0, 0 },
        { 16, 0, 0 },
        { 0, 16, 0 },
        { 0, 0, 0 },
    },
    {
        { 0, 27, 0 },
        { 0, 0, 27 },
        { 4, 4, 27 },
        { 0, 16, 27 },
    },
    {
        { 27, 0, 0 },
        { 0, 0, 0 },
        { 16, 0, 0 },
        { 16, 16, 0 },
    },
};

static constexpr int8_t junior_rc_right_eighth_to_diag_bank_thickness[4][4] = {
    {
        1,
        1,
        1,
        1,
    },
    {
        1,
        1,
        1,
        1,
    },
    {
        26,
        0,
        0,
        0,
    },
    {
        26,
        1,
        1,
        1,
    },
};

/** rct2: 0x008AB170 */
static void JuniorRCRightEighthToDiagBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilEighthToDiagTilesPaint(
        session, junior_rc_right_eighth_to_diag_bank_thickness, height, direction, trackSequence, session.TrackColours,
        junior_rc_track_pieces_right_eight_to_diag_bank, nullptr, junior_rc_right_eighth_to_diag_bank_bound_lengths,
        junior_rc_right_eighth_to_diag_bank_bound_offsets);

    switch (trackSequence)
    {
        case 0:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
            break;
        case 4:
            MetalASupportsPaintSetupRotated(
                session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
            break;
    }

    if (direction == 0 && trackSequence == 0)
    {
        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    if (direction == 3 && trackSequence == 0)
    {
        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    int32_t blockedSegments = 0;
    switch (trackSequence)
    {
        case 0:
            blockedSegments = EnumsToFlags(PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide);
            break;
        case 1:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::bottomCorner,
                PaintSegment::bottomRightSide, PaintSegment::rightCorner);
            break;
        case 2:
            blockedSegments = EnumsToFlags(
                PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner, PaintSegment::topLeftSide,
                PaintSegment::topCorner);
            break;
        case 3:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::bottomCorner, PaintSegment::bottomRightSide);
            break;
        case 4:
            blockedSegments = EnumsToFlags(
                PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide, PaintSegment::leftCorner,
                PaintSegment::topLeftSide, PaintSegment::bottomRightSide);
            break;
    }

    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB180 */
static void JuniorRCLeftEighthToOrthogonalBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence];
    JuniorRCRightEighthToDiagBankPaintSetup(
        session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

/** rct2: 0x008AB190 */
static void JuniorRCRightEighthToOrthogonalBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence];
    JuniorRCLeftEighthToDiagBankPaintSetup(
        session, ride, trackSequence, (direction + 3) % 4, height, trackElement, supportType);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiagFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaintExtra(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat[subTypeOffset], supportType.metal);
}

static void JuniorRCTrackDiagBrakes(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_brakes, defaultDiagTileOffsets,
        defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

static void JuniorRCTrackDiagBlockBrakes(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_blockbrakes[trackElement.IsBrakeClosed()],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiag25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_up[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 8, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiagFlatTo25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat_to_25_deg_up[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

static void JuniorRCPaintTrackDiagFlatTo60DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat_to_60_deg_up[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height + 6, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 64);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiag25DegUpToFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_up_to_flat[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

static void JuniorRCPaintTrackDiag60DegUpToFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_60_deg_up_to_flat[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height + 13, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 64);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiag25DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_down[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 8, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiagFlatTo25DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat_to_25_deg_down[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

static void JuniorRCPaintTrackDiagFlatTo60DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat_to_60_deg_down[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height + 7, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

template<JuniorRCSubType TSubType>
static void JuniorRCPaintTrackDiag25DegDownToFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto subTypeOffset = JuniorRCGetSubTypeOffset<TSubType>(trackElement);
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_down_to_flat[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

static void JuniorRCPaintTrackDiag60DegDownToFlat(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_60_deg_down_to_flat[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

/** rct2: 0x008AB1C0 */
static void JuniorRCDiagFlatToLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat_to_left_bank, defaultDiagTileOffsets,
        defaultDiagBoundLengths, nullptr);

    if (direction == 0 && trackSequence == 1)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_W_E_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB1D0 */
static void JuniorRCDiagFlatToRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_flat_to_right_bank, defaultDiagTileOffsets,
        defaultDiagBoundLengths, nullptr);

    if (direction == 2 && trackSequence == 2)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_E_W_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB1E0 */
static void JuniorRCDiagLeftBankToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_left_bank_to_flat, defaultDiagTileOffsets,
        defaultDiagBoundLengths, nullptr);

    if (direction == 0 && trackSequence == 1)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_FLAT_TO_RIGHT_BANK_E_W_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB1F0 */
static void JuniorRCDiagRightBankToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_right_bank_to_flat, defaultDiagTileOffsets,
        defaultDiagBoundLengths, nullptr);

    if (direction == 2 && trackSequence == 2)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_FLAT_TO_LEFT_BANK_W_E_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB220 */
static void JuniorRCDiagLeftBankTo25DegUpPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_left_bank_to_25_deg_up,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 0 && trackSequence == 1)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_W_E_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

/** rct2: 0x008AB230 */
static void JuniorRCDiagRightBankTo25DegUpPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_right_bank_to_25_deg_up,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 2 && trackSequence == 2)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_E_W_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

/** rct2: 0x008AB200 */
static void JuniorRCDiag25DegUpToLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_up_to_left_bank,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 0 && trackSequence == 1)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_W_E_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

/** rct2: 0x008AB210 */
static void JuniorRCDiag25DegUpToRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_up_to_right_bank,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 2 && trackSequence == 2)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_E_W_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

/** rct2: 0x008AB200 */
static void JuniorRCDiagLeftBankTo25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_left_bank_to_25_deg_down,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 0 && trackSequence == 1)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_RIGHT_BANK_E_W_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

/** rct2: 0x008AB210 */
static void JuniorRCDiagRightBankTo25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_right_bank_to_25_deg_down,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 2 && trackSequence == 2)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_25_DEG_UP_TO_LEFT_BANK_W_E_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 4, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 56);
}

/** rct2: 0x008AB220 */
static void JuniorRCDiag25DegDownToLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_down_to_left_bank,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 0 && trackSequence == 1)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_E_W_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

/** rct2: 0x008AB230 */
static void JuniorRCDiag25DegDownToRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_down_to_right_bank,
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (direction == 2 && trackSequence == 2)
    {
        auto imageId = session.TrackColours.WithIndex(SPR_JUNIOR_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_W_E_PART_0_2);

        PaintAddImageAsParent(session, imageId, { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } });
    }
    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48);
}

static constexpr CoordsXYZ junior_rc_diag_left_bank_bound_offsets[4] = {
    { -16, -16, 27 },
    { -16, -16, 0 },
    { -16, -16, 0 },
    { -16, -16, 0 },
};

static constexpr CoordsXYZ junior_rc_diag_right_bank_bound_offsets[4] = {
    { -16, -16, 0 },
    { -16, -16, 0 },
    { -16, -16, 27 },
    { -16, -16, 0 },
};

/** rct2: 0x008AB1A0 */
static void JuniorRCDiagLeftBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    uint8_t thickness = direction == 0 ? 0 : 1;
    TrackPaintUtilDiagTilesPaint(
        session, thickness, height, direction, trackSequence, junior_rc_track_pieces_diag_left_bank, defaultDiagTileOffsets,
        defaultDiagBoundLengths, junior_rc_diag_left_bank_bound_offsets);

    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

/** rct2: 0x008AB1B0 */
static void JuniorRCDiagRightBankPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    uint8_t thickness = direction == 2 ? 0 : 1;
    TrackPaintUtilDiagTilesPaint(
        session, thickness, height, direction, trackSequence, junior_rc_track_pieces_diag_right_bank, defaultDiagTileOffsets,
        defaultDiagBoundLengths, junior_rc_diag_right_bank_bound_offsets);

    if (trackSequence == 3)
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 0, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

static constexpr CoordsXY junior_rc_60_deg_up_bound_offsets[4] = {
    { 0, 6 },
    { 10, 29 },
    { 29, 10 },
    { 6, 0 },
};

static constexpr CoordsXY junior_rc_60_deg_up_tile_offsets[4] = {
    { 0, 6 },
    { 6, 0 },
    { 0, 6 },
    { 6, 0 },
};

static constexpr int8_t junior_rc_60_deg_up_bound_thickness[4] = {
    1,
    75,
    75,
    1,
};

static constexpr CoordsXY junior_rc_60_deg_up_bound_lengths[4] = {
    { 32, 20 },
    { 10, 1 },
    { 1, 10 },
    { 20, 32 },
};

static void JuniorRCPaintTrack60DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    auto image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_60_deg_up[subTypeOffset][direction]);

    PaintAddImageAsParent(
        session, image_id, { junior_rc_60_deg_up_tile_offsets[direction], height },
        { { junior_rc_60_deg_up_bound_offsets[direction], height },
          { junior_rc_60_deg_up_bound_lengths[direction], junior_rc_60_deg_up_bound_thickness[direction] } });

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height + 56, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height + 56, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
    }

    static constexpr int8_t support[4] = { 35, 29, 25, 32 };
    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, support[direction & 3], height,
            session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 104);
}

static void JuniorRC60DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrack60DegUp(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static constexpr CoordsXY junior_rc_25_deg_up_to_60_deg_up_bound_lengths[4][2] = {
    { { 32, 20 }, { 0, 0 } },
    { { 10, 32 }, { 2, 32 } },
    { { 32, 10 }, { 32, 2 } },
    { { 20, 32 }, { 0, 0 } },
};

static constexpr int8_t junior_rc_25_deg_up_to_60_deg_up_bound_thickness[4] = {
    1,
    43,
    43,
    1,
};

static constexpr CoordsXY junior_rc_25_deg_up_to_60_deg_up_bound_offsets[4][2] = {
    { { 0, 6 }, { 0, 0 } },
    { { 10, 0 }, { 4, 0 } },
    { { 0, 10 }, { 0, 4 } },
    { { 6, 0 }, { 0, 0 } },
};

static void JuniorRCPaintTrack25DegUpTo60DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    auto image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_60_deg_up[subTypeOffset][direction][0]);

    PaintAddImageAsParent(
        session, image_id, { junior_rc_60_deg_up_tile_offsets[direction], height },
        { { junior_rc_25_deg_up_to_60_deg_up_bound_offsets[direction][0], height },
          { junior_rc_25_deg_up_to_60_deg_up_bound_lengths[direction][0],
            junior_rc_25_deg_up_to_60_deg_up_bound_thickness[direction] } });

    if (junior_rc_track_pieces_25_deg_up_to_60_deg_up[subTypeOffset][direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_25_deg_up_to_60_deg_up[subTypeOffset][direction][1]);

        PaintAddImageAsParent(
            session, image_id, { junior_rc_60_deg_up_tile_offsets[direction], height },
            { { junior_rc_25_deg_up_to_60_deg_up_bound_offsets[direction][1], height },
              { junior_rc_25_deg_up_to_60_deg_up_bound_lengths[direction][1],
                junior_rc_25_deg_up_to_60_deg_up_bound_thickness[direction] } });
    }

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
    }

    static constexpr int8_t support[4] = { 12, 12, 12, 14 };
    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, support[direction & 3], height,
            session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRC60DegDownTo25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrack25DegUpTo60DegUp(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static void JuniorRCPaintTrack60DegUpTo25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    auto image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_60_deg_up_to_25_deg_up[subTypeOffset][direction][0]);

    PaintAddImageAsParent(
        session, image_id, { junior_rc_60_deg_up_tile_offsets[direction], height },
        { { junior_rc_25_deg_up_to_60_deg_up_bound_offsets[direction][0], height },
          { junior_rc_25_deg_up_to_60_deg_up_bound_lengths[direction][0],
            junior_rc_25_deg_up_to_60_deg_up_bound_thickness[direction] } });

    if (junior_rc_track_pieces_60_deg_up_to_25_deg_up[subTypeOffset][direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_60_deg_up_to_25_deg_up[subTypeOffset][direction][1]);

        PaintAddImageAsParent(
            session, image_id, { junior_rc_60_deg_up_tile_offsets[direction], height },
            { { junior_rc_25_deg_up_to_60_deg_up_bound_offsets[direction][1], height },
              { junior_rc_25_deg_up_to_60_deg_up_bound_lengths[direction][1],
                junior_rc_25_deg_up_to_60_deg_up_bound_thickness[direction] } });
    }

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height - 8, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 20, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRC25DegDownTo60DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrack60DegUpTo25DegUp(session, ride, trackSequence, (direction + 2) % 4, height, trackElement, supportType);
}

static void JuniorRCPaintTrackDiag60DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_60_deg_up[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 36, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 104);
}

static void JuniorRCPaintTrackDiag60DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_60_deg_down[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 28, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 104);
}

static void JuniorRCPaintTrackDiag25DegUpTo60DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_up_to_60_deg_up[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 16, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRCPaintTrackDiag60DegUpTo25DegUp(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    if (direction == 1 && trackSequence == 3)
    {
        PaintAddImageAsParent(
            session,
            session.TrackColours.WithIndex(junior_rc_track_pieces_diag_60_deg_up_to_25_deg_up[subTypeOffset][direction]),
            { -16, -16, height }, { { 0, 0, height }, { 16, 16, 1 } });
    }
    else
    {
        TrackPaintUtilDiagTilesPaint(
            session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_60_deg_up_to_25_deg_up[subTypeOffset],
            defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);
    }

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 21, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRCPaintTrackDiag25DegDownTo60DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    if (direction == 3 && trackSequence == 0)
    {
        PaintAddImageAsParent(
            session,
            session.TrackColours.WithIndex(junior_rc_track_pieces_diag_25_deg_down_to_60_deg_down[subTypeOffset][direction]),
            { -16, -16, height }, { { 0, 0, height }, { 16, 16, 1 } });
    }
    else
    {
        TrackPaintUtilDiagTilesPaint(
            session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_25_deg_down_to_60_deg_down[subTypeOffset],
            defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);
    }

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 17, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRCPaintTrackDiag60DegDownTo25DegDown(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    // There is no specific chain for the Water Coaster, use the Junior RC chain instead
    auto subTypeOffset = JuniorRCGetSubTypeOffset<JuniorRCSubType::Junior>(trackElement);

    TrackPaintUtilDiagTilesPaint(
        session, 1, height, direction, trackSequence, junior_rc_track_pieces_diag_60_deg_down_to_25_deg_down[subTypeOffset],
        defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr);

    if (trackSequence == 3)
    {
        MetalBSupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::LeftCorner, direction, 8, height, session.SupportColours);
    }

    int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence];
    PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static constexpr CoordsXY junior_rc_flat_to_60_deg_up_bound_lengths[4][2] = {
    { { 32, 24 }, { 0, 0 } },
    { { 10, 1 }, { 2, 32 } },
    { { 1, 10 }, { 32, 2 } },
    { { 24, 32 }, { 0, 0 } },
};

static constexpr int8_t junior_rc_flat_to_60_deg_up_bound_thickness[4] = {
    1,
    43,
    43,
    1,
};

static constexpr CoordsXY junior_rc_flat_to_60_deg_up_bound_offsets[4][2] = {
    { { 0, 4 }, { 0, 0 } },
    { { 10, 0 }, { 4, 0 } },
    { { 0, 10 }, { 0, 4 } },
    { { 4, 0 }, { 0, 0 } },
};

static constexpr CoordsXY junior_rc_flat_to_60_deg_up_tile_offsets[4][2] = {
    { { 12, -10 }, { 0, 0 } },
    { { 22, 9 }, { 12, -11 } },
    { { 30, 7 }, { 5, 0 } },
    { { 12, -12 }, { 0, 0 } },
};

static constexpr CoordsXY junior_rc_60_deg_up_to_flat_tile_offsets[4][2] = {
    { { 13, -9 }, { 0, 0 } },
    { { 32, 9 }, { -7, -11 } },
    { { 22, 18 }, { 2, -19 } },
    { { 13, -9 }, { 0, 0 } },
};

static void JuniorRCFlatTo60DegUpPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    bool isChained = trackElement.HasChain();
    auto image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_60_deg_up[isChained][direction][0]);

    PaintAddImageAsParent(
        session, image_id, { junior_rc_flat_to_60_deg_up_tile_offsets[direction][0], height + 24 },
        { { junior_rc_flat_to_60_deg_up_bound_offsets[direction][0], height },
          { junior_rc_flat_to_60_deg_up_bound_lengths[direction][0],
            junior_rc_flat_to_60_deg_up_bound_thickness[direction] } });

    if (junior_rc_track_pieces_flat_to_60_deg_up[isChained][direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_flat_to_60_deg_up[isChained][direction][1]);

        PaintAddImageAsParent(
            session, image_id, { junior_rc_flat_to_60_deg_up_tile_offsets[direction][1], height },
            { { junior_rc_flat_to_60_deg_up_bound_offsets[direction][1], height },
              { junior_rc_flat_to_60_deg_up_bound_lengths[direction][1],
                junior_rc_flat_to_60_deg_up_bound_thickness[direction] } });
    }

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
    }

    static constexpr int8_t support[4] = { 12, 12, 12, 14 };
    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, support[direction], height - 7,
            session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRC60DegDownToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCFlatTo60DegUpPaintSetup(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType);
}

static void JuniorRC60DegUpToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    bool isChained = trackElement.HasChain();
    auto image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_60_deg_up_to_flat[isChained][direction][0]);

    PaintAddImageAsParent(
        session, image_id, { junior_rc_60_deg_up_to_flat_tile_offsets[direction][0], height + 24 },
        { { junior_rc_flat_to_60_deg_up_bound_offsets[direction][0], height },
          { junior_rc_flat_to_60_deg_up_bound_lengths[direction][0],
            junior_rc_flat_to_60_deg_up_bound_thickness[direction] } });

    if (junior_rc_track_pieces_60_deg_up_to_flat[isChained][direction][1] != 0)
    {
        image_id = session.TrackColours.WithIndex(junior_rc_track_pieces_60_deg_up_to_flat[isChained][direction][1]);

        PaintAddImageAsParent(
            session, image_id, { junior_rc_60_deg_up_to_flat_tile_offsets[direction][1], height },
            { { junior_rc_flat_to_60_deg_up_bound_offsets[direction][1], height },
              { junior_rc_flat_to_60_deg_up_bound_lengths[direction][1],
                junior_rc_flat_to_60_deg_up_bound_thickness[direction] } });
    }

    switch (direction)
    {
        case 0:
            PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
        case 1:
            PaintUtilPushTunnelRight(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 2:
            PaintUtilPushTunnelLeft(session, height + 24, TunnelGroup::Standard, TunnelSubType::SlopeEnd);
            break;
        case 3:
            PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::SlopeStart);
            break;
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 20, height - 5, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 72);
}

static void JuniorRCFlatTo60DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRC60DegUpToFlatPaintSetup(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType);
}

/* rct2: 0x005189B0 */
template<JuniorRCSubType TSubType>
static void JuniorRC25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrack25DegUp<TSubType>(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType);
}

/* rct2: 0x00518FE8 */
template<JuniorRCSubType TSubType>
static void JuniorRCFlatTo25DegDownPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrack25DegUpToFlat<TSubType>(
        session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType);
}

/* rct2: 0x00518CCC */
template<JuniorRCSubType TSubType>
static void JuniorRC25DegDownToFlatPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    JuniorRCPaintTrackFlatTo25DegUp<TSubType>(
        session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType);
}

static void JuniorRCBoosterPaintSetup(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    if (direction & 1)
    {
        PaintAddImageAsParent(
            session, session.TrackColours.WithIndex(SPR_JUNIOR_RC_BOOSTER_NE_SW), { 0, 0, height }, { 20, 32, 1 });

        PaintUtilPushTunnelRight(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }
    else
    {
        PaintAddImageAsParent(
            session, session.TrackColours.WithIndex(SPR_JUNIOR_RC_BOOSTER_NW_SE), { 0, 0, height }, { 32, 20, 1 });

        PaintUtilPushTunnelLeft(session, height, TunnelGroup::Standard, TunnelSubType::Flat);
    }

    if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
    {
        MetalASupportsPaintSetupRotated(
            session, supportType.metal, MetalSupportPlace::Centre, direction, 0, height, session.SupportColours);
    }

    PaintUtilSetSegmentSupportHeight(
        session,
        PaintUtilRotateSegments(
            EnumsToFlags(PaintSegment::centre, PaintSegment::bottomLeftSide, PaintSegment::topRightSide), direction),
        0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight);
}

static void JuniorRCTrackOnRidePhoto(
    PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
    const TrackElement& trackElement, SupportType supportType)
{
    auto imageId = session.TrackColours.WithIndex(junior_rc_track_pieces_flat[0][direction]);
    constexpr int8_t photoCameraOffset = -1;
    PaintAddImageAsParentRotated(
        session, direction, ImageId(SPR_STATION_BASE_D, COLOUR_BLACK), { 0, 0, height + photoCameraOffset }, { 32, 32, 1 });
    DrawSupportsSideBySide(session, direction, height + photoCameraOffset, session.SupportColours, supportType.metal, 6);

    PaintAddImageAsParentRotated(session, direction, imageId, { 0, 6, height }, { { 0, 6, height + 3 }, { 32, 20, 1 } });

    TrackPaintUtilOnridePhotoPaint(session, direction, height + 3 + photoCameraOffset, trackElement);
    PaintUtilPushTunnelRotated(session, direction, height, TunnelGroup::Square, TunnelSubType::Flat);
    PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0);
    PaintUtilSetGeneralSupportHeight(session, height + 48 + photoCameraOffset);
}

/* 0x008AAA0C */
template<JuniorRCSubType TSubType> TRACK_PAINT_FUNCTION GetTrackPaintFunctionJuniorRCTemplate(int32_t trackType)
{
    switch (trackType)
    {
        case TrackElemType::Flat:
            return JuniorRCPaintTrackFlat<TSubType>;
        case TrackElemType::EndStation:
            return JuniorRCPaintStation<TSubType>;
        case TrackElemType::BeginStation:
            return JuniorRCPaintStation<TSubType>;
        case TrackElemType::MiddleStation:
            return JuniorRCPaintStation<TSubType>;
        case TrackElemType::Up25:
            return JuniorRCPaintTrack25DegUp<TSubType>;
        case TrackElemType::Up60:
            return JuniorRCPaintTrack60DegUp;
        case TrackElemType::FlatToUp25:
            return JuniorRCPaintTrackFlatTo25DegUp<TSubType>;
        case TrackElemType::Up25ToUp60:
            return JuniorRCPaintTrack25DegUpTo60DegUp;
        case TrackElemType::Up60ToUp25:
            return JuniorRCPaintTrack60DegUpTo25DegUp;
        case TrackElemType::Up25ToFlat:
            return JuniorRCPaintTrack25DegUpToFlat<TSubType>;
        case TrackElemType::Down25:
            return JuniorRC25DegDownPaintSetup<TSubType>;
        case TrackElemType::Down60:
            return JuniorRC60DegDownPaintSetup;
        case TrackElemType::FlatToDown25:
            return JuniorRCFlatTo25DegDownPaintSetup<TSubType>;
        case TrackElemType::Down25ToDown60:
            return JuniorRC25DegDownTo60DegDownPaintSetup;
        case TrackElemType::Down60ToDown25:
            return JuniorRC60DegDownTo25DegDownPaintSetup;
        case TrackElemType::Down25ToFlat:
            return JuniorRC25DegDownToFlatPaintSetup<TSubType>;
        case TrackElemType::LeftQuarterTurn5Tiles:
            return JuniorRCLeftQuarterTurn5TilesPaintSetup;
        case TrackElemType::RightQuarterTurn5Tiles:
            return JuniorRCRightQuarterTurn5TilesPaintSetup;
        case TrackElemType::FlatToLeftBank:
            return JuniorRCFlatToLeftBankPaintSetup;
        case TrackElemType::FlatToRightBank:
            return JuniorRCFlatToRightBankPaintSetup;
        case TrackElemType::LeftBankToFlat:
            return JuniorRCLeftBankToFlatPaintSetup;
        case TrackElemType::RightBankToFlat:
            return JuniorRCRightBankToFlatPaintSetup;
        case TrackElemType::BankedLeftQuarterTurn5Tiles:
            return JuniorRCBankedLeftQuarterTurn5TilesPaintSetup;
        case TrackElemType::BankedRightQuarterTurn5Tiles:
            return JuniorRCBankedRightQuarterTurn5TilesPaintSetup;
        case TrackElemType::LeftBankToUp25:
            return JuniorRCLeftBankTo25DegUpPaintSetup;
        case TrackElemType::RightBankToUp25:
            return JuniorRCRightBankTo25DegUpPaintSetup;
        case TrackElemType::Up25ToLeftBank:
            return JuniorRC25DegUpToLeftBankPaintSetup;
        case TrackElemType::Up25ToRightBank:
            return JuniorRC25DegUpToRightBankPaintSetup;
        case TrackElemType::LeftBankToDown25:
            return JuniorRCLeftBankTo25DegDownPaintSetup;
        case TrackElemType::RightBankToDown25:
            return JuniorRCRightBankTo25DegDownPaintSetup;
        case TrackElemType::Down25ToLeftBank:
            return JuniorRC25DegDownToLeftBankPaintSetup;
        case TrackElemType::Down25ToRightBank:
            return JuniorRC25DegDownToRightBankPaintSetup;
        case TrackElemType::LeftBank:
            return JuniorRCLeftBankPaintSetup;
        case TrackElemType::RightBank:
            return JuniorRCRightBankPaintSetup;
        case TrackElemType::LeftQuarterTurn5TilesUp25:
            return JuniorRCPaintTrackLeftQuarterTurn5Tiles25DegUp;
        case TrackElemType::RightQuarterTurn5TilesUp25:
            return JuniorRCPaintTrackRightQuarterTurn5Tiles25DegUp;
        case TrackElemType::LeftQuarterTurn5TilesDown25:
            return JuniorRCLeftQuarterTurn5Tiles25DegDownPaintSetup;
        case TrackElemType::RightQuarterTurn5TilesDown25:
            return JuniorRCRightQuarterTurn5Tiles25DegDownPaintSetup;
        case TrackElemType::SBendLeft:
            return JuniorRCSBendLeftPaintSetup;
        case TrackElemType::SBendRight:
            return JuniorRCSBendRightPaintSetup;

        case TrackElemType::LeftQuarterTurn3Tiles:
            return JuniorRCLeftQuarterTurn3TilesPaintSetup;
        case TrackElemType::RightQuarterTurn3Tiles:
            return JuniorRCRightQuarterTurn3TilesPaintSetup;
        case TrackElemType::LeftBankedQuarterTurn3Tiles:
            return JuniorRCLeftQuarterTurn3TilesBankPaintSetup;
        case TrackElemType::RightBankedQuarterTurn3Tiles:
            return JuniorRCRightQuarterTurn3TilesBankPaintSetup;
        case TrackElemType::LeftQuarterTurn3TilesUp25:
            return JuniorRCLeftQuarterTurn3Tiles25DegUpPaintSetup;
        case TrackElemType::RightQuarterTurn3TilesUp25:
            return JuniorRCPaintTrackRightQuarterTurn3Tiles25DegUp;
        case TrackElemType::LeftQuarterTurn3TilesDown25:
            return JuniorRCLeftQuarterTurn3Tiles25DegDownPaintSetup;
        case TrackElemType::RightQuarterTurn3TilesDown25:
            return JuniorRCPaintTrackRightQuarterTurn3Tiles25DegDown;

        case TrackElemType::FlatToUp60:
            return JuniorRCFlatTo60DegUpPaintSetup;
        case TrackElemType::Up60ToFlat:
            return JuniorRC60DegUpToFlatPaintSetup;
        case TrackElemType::FlatToDown60:
            return JuniorRCFlatTo60DegDownPaintSetup;
        case TrackElemType::Down60ToFlat:
            return JuniorRC60DegDownToFlatPaintSetup;

        case TrackElemType::LeftHalfBankedHelixUpSmall:
            return JuniorRCLeftHalfBankedHelixUpSmallPaintSetup;
        case TrackElemType::RightHalfBankedHelixUpSmall:
            return JuniorRCRightHalfBankedHelixUpSmallPaintSetup;
        case TrackElemType::LeftHalfBankedHelixDownSmall:
            return JuniorRCLeftHalfBankedHelixDownSmallPaintSetup;
        case TrackElemType::RightHalfBankedHelixDownSmall:
            return JuniorRCRightHalfBankedHelixDownSmallPaintSetup;
        case TrackElemType::LeftHalfBankedHelixUpLarge:
            return JuniorRCLeftHalfBankedHelixUpLargePaintSetup;
        case TrackElemType::RightHalfBankedHelixUpLarge:
            return JuniorRCRightHalfBankedHelixUpLargePaintSetup;
        case TrackElemType::LeftHalfBankedHelixDownLarge:
            return JuniorRCLeftHalfBankedHelixDownLargePaintSetup;
        case TrackElemType::RightHalfBankedHelixDownLarge:
            return JuniorRCRightHalfBankedHelixDownLargePaintSetup;

        case TrackElemType::Brakes:
            return JuniorRCBrakePaintSetup;

        case TrackElemType::LeftEighthToDiag:
            return JuniorRCLeftEighthToDiagPaintSetup;
        case TrackElemType::RightEighthToDiag:
            return JuniorRCRightEighthToDiagPaintSetup;
        case TrackElemType::LeftEighthToOrthogonal:
            return JuniorRCLeftEighthToOrthogonalPaintSetup;
        case TrackElemType::RightEighthToOrthogonal:
            return JuniorRCRightEighthToOrthogonalPaintSetup;
        case TrackElemType::LeftEighthBankToDiag:
            return JuniorRCLeftEighthToDiagBankPaintSetup;
        case TrackElemType::RightEighthBankToDiag:
            return JuniorRCRightEighthToDiagBankPaintSetup;
        case TrackElemType::LeftEighthBankToOrthogonal:
            return JuniorRCLeftEighthToOrthogonalBankPaintSetup;
        case TrackElemType::RightEighthBankToOrthogonal:
            return JuniorRCRightEighthToOrthogonalBankPaintSetup;
        case TrackElemType::DiagFlat:
            return JuniorRCPaintTrackDiagFlat<TSubType>;
        case TrackElemType::DiagUp25:
            return JuniorRCPaintTrackDiag25DegUp<TSubType>;
        case TrackElemType::DiagUp60:
            return JuniorRCPaintTrackDiag60DegUp;
        case TrackElemType::DiagFlatToUp25:
            return JuniorRCPaintTrackDiagFlatTo25DegUp<TSubType>;
        case TrackElemType::DiagUp25ToUp60:
            return JuniorRCPaintTrackDiag25DegUpTo60DegUp;
        case TrackElemType::DiagUp60ToUp25:
            return JuniorRCPaintTrackDiag60DegUpTo25DegUp;
        case TrackElemType::DiagUp25ToFlat:
            return JuniorRCPaintTrackDiag25DegUpToFlat<TSubType>;
        case TrackElemType::DiagDown25:
            return JuniorRCPaintTrackDiag25DegDown<TSubType>;
        case TrackElemType::DiagDown60:
            return JuniorRCPaintTrackDiag60DegDown;
        case TrackElemType::DiagFlatToDown25:
            return JuniorRCPaintTrackDiagFlatTo25DegDown<TSubType>;
        case TrackElemType::DiagDown25ToDown60:
            return JuniorRCPaintTrackDiag25DegDownTo60DegDown;
        case TrackElemType::DiagDown60ToDown25:
            return JuniorRCPaintTrackDiag60DegDownTo25DegDown;
        case TrackElemType::DiagDown25ToFlat:
            return JuniorRCPaintTrackDiag25DegDownToFlat<TSubType>;

        case TrackElemType::DiagFlatToLeftBank:
            return JuniorRCDiagFlatToLeftBankPaintSetup;
        case TrackElemType::DiagFlatToRightBank:
            return JuniorRCDiagFlatToRightBankPaintSetup;
        case TrackElemType::DiagLeftBankToFlat:
            return JuniorRCDiagLeftBankToFlatPaintSetup;
        case TrackElemType::DiagRightBankToFlat:
            return JuniorRCDiagRightBankToFlatPaintSetup;
        case TrackElemType::DiagLeftBankToUp25:
            return JuniorRCDiagLeftBankTo25DegUpPaintSetup;
        case TrackElemType::DiagRightBankToUp25:
            return JuniorRCDiagRightBankTo25DegUpPaintSetup;
        case TrackElemType::DiagUp25ToLeftBank:
            return JuniorRCDiag25DegUpToLeftBankPaintSetup;
        case TrackElemType::DiagUp25ToRightBank:
            return JuniorRCDiag25DegUpToRightBankPaintSetup;
        case TrackElemType::DiagLeftBankToDown25:
            return JuniorRCDiagLeftBankTo25DegDownPaintSetup;
        case TrackElemType::DiagRightBankToDown25:
            return JuniorRCDiagRightBankTo25DegDownPaintSetup;
        case TrackElemType::DiagDown25ToLeftBank:
            return JuniorRCDiag25DegDownToLeftBankPaintSetup;
        case TrackElemType::DiagDown25ToRightBank:
            return JuniorRCDiag25DegDownToRightBankPaintSetup;
        case TrackElemType::DiagLeftBank:
            return JuniorRCDiagLeftBankPaintSetup;
        case TrackElemType::DiagRightBank:
            return JuniorRCDiagRightBankPaintSetup;

        case TrackElemType::BlockBrakes:
            return JuniorRCBlockBrakePaintSetup;
        case TrackElemType::DiagBrakes:
            return JuniorRCTrackDiagBrakes;
        case TrackElemType::DiagBlockBrakes:
            return JuniorRCTrackDiagBlockBrakes;

        case TrackElemType::Booster:
            return JuniorRCBoosterPaintSetup;

        case TrackElemType::DiagDown60ToFlat:
            return JuniorRCPaintTrackDiag60DegDownToFlat;
        case TrackElemType::DiagUp60ToFlat:
            return JuniorRCPaintTrackDiag60DegUpToFlat;
        case TrackElemType::DiagFlatToUp60:
            return JuniorRCPaintTrackDiagFlatTo60DegUp;
        case TrackElemType::DiagFlatToDown60:
            return JuniorRCPaintTrackDiagFlatTo60DegDown;

        case TrackElemType::OnRidePhoto:
            return JuniorRCTrackOnRidePhoto;
    }
    return nullptr;
}

TRACK_PAINT_FUNCTION GetTrackPaintFunctionJuniorRC(int32_t trackType)
{
    return GetTrackPaintFunctionJuniorRCTemplate<JuniorRCSubType::Junior>(trackType);
}

TRACK_PAINT_FUNCTION GetTrackPaintFunctionWaterRC(int32_t trackType)
{
    return GetTrackPaintFunctionJuniorRCTemplate<JuniorRCSubType::WaterCoaster>(trackType);
}
